{"version":3,"file":"assets/chunk.4f5f3c7c3d06a02ba79b.js","mappings":"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","sources":["./components/download-app/index.hbs","./components/download-app/index.ts","./components/modals/video/download-clip/base-export.ts","./components/modals/video/download-clip/camera-selector/index.hbs","./components/modals/video/download-clip/camera-selector/index.ts","./components/modals/video/download-clip/duration/index.hbs","./components/modals/video/download-clip/duration/index.ts","./components/modals/video/download-clip/export-options/index.hbs","./components/modals/video/download-clip/export-options/index.ts","./components/modals/video/download-clip/warning.hbs","./components/modals/video/download-clip/warning.ts","./components/ui/page-blocking-loading-overlay/index.hbs","./components/ui/page-blocking-loading-overlay/index.ts","./components/ui/simple-pagination/index.hbs","./components/ui/simple-pagination/index.ts","./components/video/appearance-search/results-toolbar/index.hbs","./components/video/appearance-search/results-toolbar/index.ts","./components/video/appearance-search/search-sidebar/index.hbs","./components/video/appearance-search/search-sidebar/index.ts","./components/video/clips/clip-display/base-clip-display/index.js","./components/video/clips/playable-clip/base-playable-clip.ts","./components/video/live-video/index.hbs","./components/video/live-video/index.ts","./components/video/video-player/overlay/live-overlay/index.hbs","./components/video/video-player/overlay/live-overlay/index.ts","./components/video/video-player/overlay/warning-sound-popover/index.hbs","./components/video/video-player/overlay/warning-sound-popover/index.ts","./components/video/video-player/overlay/associated-devices-action-popover/index.hbs","./components/video/video-player/overlay/associated-devices-action-popover/index.ts","./components/video/video-player/live-view-player/index.hbs","./components/video/video-player/live-view-player/index.js","./components/video/video-player/oesp-osd/index.hbs","./components/video/video-player/oesp-osd/index.js","./components/video/video-player/overlay/base-live-overlay/index.ts","./components/svg-paths/icn-view-threesixty-full/index.hbs","./components/svg-paths/icn-view-threesixty-full/index.ts","./components/svg-paths/icn-view-threesixty-half-pano/index.hbs","./components/svg-paths/icn-view-threesixty-half-pano/index.ts","./components/svg-paths/icn-view-threesixty-interactive/index.hbs","./components/svg-paths/icn-view-threesixty-interactive/index.ts","./components/svg-paths/icn-view-threesixty-two-pano/index.hbs","./components/svg-paths/icn-view-threesixty-two-pano/index.ts","./components/video/video-player/overlay/dewarping-selector-panel/index.hbs","./components/video/video-player/overlay/dewarping-selector-panel/index.ts","./components/modals/video/edit-onvif-ptz-presets/index.hbs","./components/modals/video/edit-onvif-ptz-presets/index.ts","./components/modals/video/new-onvif-ptz-preset/index.hbs","./components/modals/video/new-onvif-ptz-preset/index.ts","./components/video/video-player/overlay/onvif-ptz-panel/index.hbs","./components/video/video-player/overlay/onvif-ptz-panel/index.ts","./components/video/video-player/overlay/ptz-popover-menu/index.hbs","./components/video/video-player/overlay/ptz-popover-menu/index.ts","./components/video/video-player/overlay/general-overlay-features/index.hbs","./components/video/video-player/overlay/general-overlay-features/index.ts","./components/video/video-player/overlay/overlay-border/index.hbs","./components/video/video-player/overlay/overlay-border/index.ts","./components/video/video-player/overlay/two-way-audio-buttons/index.hbs","./components/video/video-player/overlay/two-way-audio-buttons/index.ts","./components/modals/date-time-picker/index.hbs","./components/modals/date-time-picker/index.ts","./components/video/video-player/playback-features/intervals-control.ts","./components/video/video-player/playback-features/page-state.ts","./components/video/video-player/playback-features/playback-control.ts","./components/video/event-history-item/index.hbs","./components/video/event-history-item/index.ts","./components/video/event-history/index.hbs","./components/video/event-history/index.ts","./components/video/advanced-video-search/results-status-bar/index.hbs","./components/video/advanced-video-search/results-status-bar/index.ts","./components/video/advanced-video-search/found-search-results/index.hbs","./components/video/advanced-video-search/found-search-results/index.ts","./components/video/video-timeline/index.hbs","./components/video/video-timeline/index.ts","./components/video/video-player/playback-features/index.hbs","./components/video/video-player/playback-features/index.ts","./components/modals/video/download-clip/svr/index.hbs","./components/modals/video/download-clip/svr/index.ts","./components/video/video-player/playback-features/svr-playback-features/index.ts","./components/video/video-streaming/video-streaming-players/operator-title/index.hbs","./components/video/video-streaming/video-streaming-players/operator-title/index.ts","./components/video/video-player/overlay/playback-overlay/index.hbs","./components/video/video-player/overlay/playback-overlay/index.ts","./components/video/video-player/base-playback-player/index.hbs","./components/video/video-player/base-playback-player/index.ts","./components/video/video-streaming/video-streaming-players/index.hbs","./components/video/video-streaming/video-streaming-players/index.ts","./components/video/video-streaming/video-streaming-toolbar/shortcut-table/index.hbs","./components/video/video-streaming/video-streaming-toolbar/shortcut-table/index.ts","./components/modals/video/save-camera-group/index.hbs","./components/modals/video/save-camera-group/index.ts","./components/video/video-streaming/video-streaming-toolbar/video-streaming-cameras-selector/index.hbs","./components/video/video-streaming/video-streaming-toolbar/video-streaming-cameras-selector/index.ts","./components/video/video-streaming/video-streaming-toolbar/keyboard-shortcuts-popover/index.hbs","./components/video/video-streaming/video-streaming-toolbar/keyboard-shortcuts-popover/index.ts","./components/video/video-streaming/video-streaming-toolbar/layouts-popover/index.hbs","./components/video/video-streaming/video-streaming-toolbar/layouts-popover/index.ts","./components/video/video-streaming/video-streaming-toolbar/layout-zoom-features/index.hbs","./components/video/video-streaming/video-streaming-toolbar/layout-zoom-features/index.ts","./components/video/live-video/display-options-dropdown/index.hbs","./components/video/live-video/display-options-dropdown/index.ts","./components/video/video-streaming/video-streaming-toolbar/index.hbs","./components/video/video-streaming/video-streaming-toolbar/index.ts","./helpers/exists.ts","./video/svr-timeline/controller.ts","./video/thumbnail-search/route.ts","../../../../../node_modules/.pnpm/date-fns@2.29.3/node_modules/date-fns/esm/startOfMinute/index.js","../rewritten-packages/ember-cli-string-helpers.7aab1772/node_modules/ember-cli-string-helpers/-private/create-string-helper.js","../rewritten-packages/ember-cli-string-helpers.7aab1772/node_modules/ember-cli-string-helpers/helpers/html-safe.js","../rewritten-packages/ember-cli-string-helpers.7aab1772/node_modules/ember-cli-string-helpers/helpers/uppercase.js","../rewritten-packages/ember-cli-string-helpers.7aab1772/node_modules/ember-cli-string-helpers/utils/uppercase.js","../../../../../node_modules/.pnpm/date-fns@2.29.3/node_modules/date-fns/esm/addSeconds/index.js","../../../../../node_modules/.pnpm/date-fns@2.29.3/node_modules/date-fns/esm/minutesToSeconds/index.js","../../../../../node_modules/.pnpm/date-fns@2.29.3/node_modules/date-fns/esm/subSeconds/index.js"],"sourcesContent":["import { precompileTemplate } from \"@ember/template-compilation\";\nexport default precompileTemplate(\"
\\n {{#if this.showDownloadScreen}}\\n
\\n

{{tc this \\'recommendApp\\'}}

\\n \\n
\\n {{else}}\\n {{yield}}\\n {{/if}}\\n
\",{ moduleName: \"customer-site/components/download-app/index.hbs\" })","/* import __COLOCATED_TEMPLATE__ from './index.hbs'; */\nimport Component from '@glimmer/component';\nimport { isMobileBrowser } from '@adc/ember-utils/utils/browser-helpers';\nimport { action, computed } from '@ember/object';\nimport { inject as service } from '@ember/service';\nimport { intlPath } from '@adc/i18n/path';\nimport { AppDownload } from '../../enums/CustomerPageUrl';\n\nimport './_style.scss';\nimport type { Registry as ServiceRegistry } from '@ember/service';\n\nexport interface DownloadAppSignature {\n Element: HTMLDivElement;\n Args: {\n bypassDeviceCheck?: boolean;\n };\n Blocks: {\n default: [];\n };\n}\n\n/**\n * @classdesc\n * Controller from which other pages can extend to display a download mobile app message for users on mobile web.\n */\n@intlPath({ path: 'download-app' })\nexport default class DownloadApp extends Component {\n @service declare navigation: ServiceRegistry['navigation'];\n\n /**\n * Determines if a user is on a mobile device.\n */\n isMobileOrTablet = isMobileBrowser();\n\n /**\n * If we should show the screen for downloading the app.\n */\n @computed('args.bypassDeviceCheck', 'isMobileOrTablet')\n get showDownloadScreen(): boolean {\n return this.isMobileOrTablet && !this.args.bypassDeviceCheck;\n }\n\n /**\n * Redirects to the mobile app download page in the appropriate app store.\n */\n @action\n redirectToApp(): void {\n window.open(this.navigation.getRouteItem(AppDownload)?.url);\n }\n}\n\ndeclare module '@glint/environment-ember-loose/registry' {\n export default interface Registry {\n DownloadApp: typeof DownloadApp;\n }\n}\n","import Component from '@glimmer/component';\nimport { tracked } from '@glimmer/tracking';\nimport { get } from '@ember/object';\nimport { action, computed } from '@ember/object';\nimport { alias, bool } from '@ember/object/computed';\nimport { inject as service } from '@ember/service';\nimport {\n ExportOptionDirectDownload,\n ExportOptionAddToSavedClips,\n ExportOptionDirectDownloadAddToSavedClips\n} from 'customer-site/components/video/video-player/playback-features/index';\nimport { SDCard, SVR } from 'customer-site/enums/ClipExportType';\nimport { sentryWithScopeAndError } from '@adc/app-infrastructure/utils/sentry';\nimport { getModalFooterButton } from '@adc/ui-components/components/modals/base/footer/modal-footer';\nimport { downloadFile } from '@adc/ui-components/utils/download-file';\nimport { isAfter, isEqual } from 'date-fns';\n\nimport './_style.scss';\nimport type ADCIntlService from '@adc/i18n/services/adc-intl';\nimport type { ModalButtonConfig } from '@adc/ui-components/components/modals/base/footer/modal-footer';\nimport type ModalService from '@adc/ui-components/services/modals';\nimport type NotificationManager from '@adc/ui-components/services/notification-manager';\nimport type BaseCamera from 'customer-site/models/video/devices/base-camera';\nimport type AjaxService from 'customer-site/services/ajax';\nimport type ClipDownloader from 'customer-site/services/video/clip-downloader';\nimport type ClipUploader from 'customer-site/services/video/clip-uploader';\n\nenum ExportType {\n Download,\n Upload,\n DownloadAndUpload\n}\n\nenum ExportStatus {\n fileRequestError,\n fileNotFound,\n preparingFileDownload,\n downloadInProgress,\n preparingUpload,\n uploadInProgress,\n preparingDownloadAndUpload,\n downloadAndUploadInProgress\n}\n\nexport type ClipExportModel = {\n minDate: Date;\n maxDate: Date;\n defaultDate: Date;\n cameras: T[];\n defaultCamera: T;\n durations: { [key: number]: number[] };\n disableCameraSelection: boolean;\n streamResolutionGreaterThanEightMegapixels: boolean;\n exportOptions?: number[];\n};\n\nexport interface BaseVideoClipExportModalArgs {\n model: ClipExportModel;\n}\n\n/**\n * @classdesc\n * Displays a modal date time picker object with options for clip download\n */\nexport default abstract class BaseVideoClipExportModal<\n T extends BaseVideoClipExportModalArgs = BaseVideoClipExportModalArgs\n> extends Component {\n @service declare ajax: AjaxService;\n @service declare intl: ADCIntlService;\n @service declare notificationManager: NotificationManager;\n @service declare modals: ModalService;\n @service('video.clip-downloader') declare clipDownloader: ClipDownloader;\n @service('video.clip-uploader') declare clipUploader: ClipUploader;\n\n /**\n * Current Message that the inset modal should display.\n * This is calculated when the user presses the \"export\" button.\n */\n @tracked clipExportModalMessage = '';\n\n /**\n * The footer buttons the inset modal should display.\n * This is calculated when the user presses the \"export\" button.\n */\n @tracked warningButtons: ModalButtonConfig[] = [];\n\n /**\n * The selected date from the date-time picker on the modal.\n */\n @tracked selectedDateTime?: Date;\n\n @tracked selectedCameraId: string;\n @tracked duration: number;\n @tracked showWarning = false;\n @tracked includeAudio = false;\n\n /**\n * Selected export option.\n */\n @tracked selectedExportOption = ExportOptionDirectDownload;\n\n constructor(owner: unknown, args: BaseVideoClipExportModalArgs) {\n super(owner, args);\n\n const { model } = this.args;\n\n this.selectedCameraId = (model.defaultCamera ?? model.cameras[0])?.id ?? '';\n\n this.duration = this.durations[0];\n }\n\n abstract clipExportType: number;\n abstract get isDownloadTaskRunning(): boolean;\n abstract get isUploadClipTaskRunning(): boolean;\n\n /**\n * Returns translated strings, trying local first, then defaulting to base class.\n */\n protected getTranslation(key: string): string {\n return this.intl.t(`components.modals.video.download-clip.${key}`);\n }\n\n /**\n * The translation for the passed export status.\n */\n private getExportStatusTranslation(status: ExportStatus): string {\n return this.getTranslation(ExportStatus[status]);\n }\n\n @bool('args.model.exportOptions.length')\n declare isClipDownload: boolean;\n\n /**\n * The title text.\n */\n get titleText(): string {\n return this.getTranslation('title');\n }\n\n @computed('isClipDownload')\n get exportResource(): string {\n return this.intl.t(this.isClipDownload ? 'generic.export' : 'generic.download');\n }\n\n @computed('args', 'isClipDownload', 'selectedExportOption')\n get durations(): number[] {\n const { model } = this.args;\n\n // Clip download/upload durations.\n if (this.isClipDownload) {\n return model.durations[this.selectedExportOption];\n }\n\n // Thumbnail download durations.\n return model.durations[ExportOptionDirectDownload];\n }\n\n /**\n * Whether camera selection should be disabled\n */\n @alias('args.model.disableCameraSelection')\n declare disableCameraSelection: boolean;\n\n /**\n * Whether the camera's image resolution is greater than eight megapixels\n */\n @alias('args.model.streamResolutionGreaterThanEightMegapixels')\n declare streamResolutionGreaterThanEightMegapixels: boolean;\n\n /**\n * Does the clip download support audio?\n */\n @alias('args.model.defaultCamera.videoSource.supportsAudioForProxyStream')\n declare supportsAudioDownload: boolean;\n\n /**\n * Trigger the download process after the user click download.\n * Must be overridden.\n */\n triggerDownload(): void {\n // Start Clip Download global service.\n this.clipDownloader.downloadClip(this.clipExportType, this.requestDownloadUrls, this.handleDownload);\n }\n\n abstract requestDownloadUrls(): Promise<{ value: string }>;\n\n /**\n * Download the clip\n */\n @action handleDownload(downloadUrl: string): void {\n downloadFile(downloadUrl);\n }\n\n /**\n * Handle the cancel button. Decide whether the cancel button will also\n * involve cancelling the current download/upload.\n */\n @action cancelExport(cancelTask: boolean, exportType: ExportType): false {\n // Cancel the current export task the service is processing\n if (cancelTask) {\n if (\n [ExportType.Download, ExportType.DownloadAndUpload].includes(exportType) &&\n this.isDownloadTaskRunning\n ) {\n this.clipDownloader.cancelClipExport(this.clipExportType);\n }\n\n if (\n [ExportType.Upload, ExportType.DownloadAndUpload].includes(exportType) &&\n this.isUploadClipTaskRunning\n ) {\n this.clipUploader.cancelClipExport(this.clipExportType);\n }\n }\n\n // Hide the inset modal popup.\n this.showWarning = false;\n\n // Returning false will ensure the closeModal action isn't sent.\n return false;\n }\n\n /**\n * Updates the Inset Modal with the appropriate footer buttons and display text.\n */\n private updateExportConfirmationModal(exportType: ExportType, exportStatus: ExportStatus): void {\n const fnGetButton = (key: string, fn: VoidFunction, isPrimary = false) =>\n getModalFooterButton(this.intl.t(`generic.${key}`), fn, isPrimary ? 'btn-color-primary' : '');\n\n let taskIsRunning = false,\n confirmButtonAction;\n\n switch (exportType) {\n case ExportType.Download:\n taskIsRunning = exportStatus === ExportStatus.preparingFileDownload;\n confirmButtonAction = taskIsRunning ? this.modals.closeModal : this.startDownloading;\n break;\n case ExportType.Upload:\n taskIsRunning = exportStatus === ExportStatus.preparingUpload;\n confirmButtonAction = taskIsRunning ? this.modals.closeModal : this.startUpload;\n break;\n case ExportType.DownloadAndUpload:\n taskIsRunning = exportStatus === ExportStatus.preparingDownloadAndUpload;\n confirmButtonAction = taskIsRunning ? this.modals.closeModal : this.startDownloadAndUpload;\n break;\n }\n\n this.warningButtons = [\n fnGetButton('cancel', () => this.cancelExport(taskIsRunning, exportType)),\n fnGetButton(taskIsRunning ? 'continue' : 'ok', confirmButtonAction, true)\n ];\n\n this.clipExportModalMessage = this.getExportStatusTranslation(exportStatus);\n }\n\n /**\n * Do some pre-download checks to make sure there is available video.\n * If pre-download checks fail update the inset modal.\n *\n * Otherwise, trigger the download task.\n */\n @action startDownloading(): void {\n const { selectedCameraId, notificationManager } = this,\n { model } = this.args,\n { maxDate } = model,\n downloadStartDate = this.selectedDateTime || model.defaultDate,\n sentryExtras = { cameraId: selectedCameraId },\n sentryTags = { feature: 'Clip Download' };\n\n // Double check that camera is present\n if (!model.cameras.find((item) => get(item, 'id') === selectedCameraId)) {\n const sentryErrorMessage = 'Could not find camera during clip upload.';\n sentryWithScopeAndError(sentryErrorMessage, sentryExtras, sentryTags);\n\n // Display generic unable to download error as a notification and on the inset modal.\n notificationManager.addError(this.getExportStatusTranslation(ExportStatus.fileRequestError));\n this.updateExportConfirmationModal(ExportType.Download, ExportStatus.fileRequestError);\n return;\n }\n\n // If the user has the timeline bar all the way at the end of bar or the camera has no recordings at all then error.\n if (isEqual(downloadStartDate, maxDate) || isAfter(downloadStartDate, maxDate)) {\n const sentryErrorMessage = \"User selected space where recording doesn't exist yet.\";\n sentryWithScopeAndError(sentryErrorMessage, sentryExtras, sentryTags);\n\n // No Video Available at this time error as a notification and on the inset modal.\n notificationManager.addError(this.getExportStatusTranslation(ExportStatus.fileNotFound));\n this.updateExportConfirmationModal(ExportType.Download, ExportStatus.fileNotFound);\n return;\n }\n\n // Ensure that current download is canceled before starting download\n if (this.isDownloadTaskRunning) {\n this.clipDownloader.cancelClipExport(this.clipExportType);\n }\n\n // Pre-download steps good start clip download service now.\n this.triggerDownload();\n }\n\n /**\n * Upload clip to Saved Video Clips.\n */\n abstract uploadVideoClips(): Promise<{ metaData: { UploadClipStatus: boolean } }>;\n\n /**\n * Do some pre-upload checks to make sure there is available video.\n * If pre-upload checks fail update the inset modal.\n *\n * Otherwise, trigger the upload task.\n */\n @action startUpload(): void {\n const { selectedCameraId, notificationManager } = this,\n { model } = this.args,\n { maxDate } = model,\n uploadStartDate = this.selectedDateTime || model.defaultDate,\n sentryExtras = { cameraId: selectedCameraId },\n sentryTags = { feature: 'Clip Upload to Cloud' };\n\n // Double check that camera is present.\n if (!model.cameras.find((item) => get(item, 'id') === selectedCameraId)) {\n const sentryErrorMessage = 'Could not find camera during clip upload.';\n sentryWithScopeAndError(sentryErrorMessage, sentryExtras, sentryTags);\n\n // Display generic unable to upload error as a notification and on the inset modal.\n notificationManager.addError(this.getTranslation('cameraNotFound'));\n this.updateExportConfirmationModal(ExportType.Upload, ExportStatus.fileNotFound);\n return;\n }\n\n // If the user has the timeline bar all the way at the end of bar or the camera has no recordings at all then error.\n if (isEqual(uploadStartDate, maxDate) || isAfter(uploadStartDate, maxDate)) {\n const sentryErrorMessage = \"User selected space where recording doesn't exist yet.\";\n sentryWithScopeAndError(sentryErrorMessage, sentryExtras, sentryTags);\n\n // No Video Available at this time error as a notification and on the inset modal.\n notificationManager.addError(this.getTranslation('timeIncorrect'));\n this.updateExportConfirmationModal(ExportType.Upload, ExportStatus.fileRequestError);\n return;\n }\n\n // Ensure that current upload is canceled before starting upload.\n if (this.isUploadClipTaskRunning) {\n this.clipUploader.cancelClipExport(this.clipExportType);\n }\n\n // Pre-upload steps good start clip upload service now.\n this.clipUploader.uploadClip(this.clipExportType, this.uploadVideoClips);\n }\n\n /**\n * Starts the task for downloading and uploading simultaneously\n */\n @action startDownloadAndUpload(): void {\n this.startDownloading();\n this.startUpload();\n }\n\n /**\n * When a new date, time, and other options is selected (eg. when Export button is pressed).\n */\n @action exportVideo(newDate: Date): false {\n if (\n this.clipExportType === SDCard &&\n !(\n // SD card thumbnail download has no export option.\n (\n this.selectedExportOption === undefined ||\n // Video clip direct download option.\n this.selectedExportOption === ExportOptionDirectDownload\n )\n )\n ) {\n return false;\n }\n\n // Set the newly selected date time,\n // and show the warning popup detailing the progress and disable all controls.\n Object.assign(this, {\n selectedDateTime: newDate,\n showWarning: true\n });\n\n if (this.selectedExportOption === ExportOptionDirectDownload) {\n // Update Inset Modal's footer buttons and display message.\n const exportStatus = this.isDownloadTaskRunning\n ? ExportStatus.downloadInProgress\n : ExportStatus.preparingFileDownload;\n this.updateExportConfirmationModal(ExportType.Download, exportStatus);\n\n // If a download task is already running do not start auto downloading.\n // Instead we will verify the user is fine with cancelling the current download.\n if (this.isDownloadTaskRunning) {\n return false;\n }\n\n // Start the clip download.\n this.startDownloading();\n } else if (this.selectedExportOption === ExportOptionAddToSavedClips && this.clipExportType === SVR) {\n // Update Inset Modal's footer buttons and display message.\n const exportStatus = this.isUploadClipTaskRunning\n ? ExportStatus.uploadInProgress\n : ExportStatus.preparingUpload;\n this.updateExportConfirmationModal(ExportType.Upload, exportStatus);\n\n // If a upload task is already running do not start auto uploading.\n // Instead we will verify the user is fine with cancelling the current upload.\n if (this.isUploadClipTaskRunning) {\n return false;\n }\n\n // Start the clip upload.\n this.startUpload();\n } else if (\n this.selectedExportOption === ExportOptionDirectDownloadAddToSavedClips &&\n this.clipExportType === SVR\n ) {\n const isDownloadOrUploadTaskRunning = this.isDownloadTaskRunning || this.isUploadClipTaskRunning;\n\n const exportStatus = isDownloadOrUploadTaskRunning\n ? ExportStatus.downloadAndUploadInProgress\n : ExportStatus.preparingDownloadAndUpload;\n this.updateExportConfirmationModal(ExportType.DownloadAndUpload, exportStatus);\n\n if (isDownloadOrUploadTaskRunning) {\n return false;\n }\n\n // Start the clip download/upload\n this.startDownloadAndUpload();\n }\n\n return false;\n }\n}\n","import { precompileTemplate } from \"@ember/template-compilation\";\nexport default precompileTemplate(\"
\\n \\n \\n \\n
\",{ moduleName: \"customer-site/components/modals/video/download-clip/camera-selector/index.hbs\" })","/* import __COLOCATED_TEMPLATE__ from './index.hbs'; */\nimport Component from '@glimmer/component';\nimport { computed } from '@ember/object';\nimport DropdownSelectItem from '@adc/ui-components/utils/dropdown-select-item';\n\nimport type BaseCamera from 'customer-site/models/video/devices/base-camera';\n\ninterface ModalsVideoDownloadClipCameraSelectorArgs {\n cameras?: BaseCamera[];\n disableCameraSelection?: boolean;\n selectedCameraId: string;\n 'value-change': (v: string) => void;\n}\n\ninterface ModalsVideoDownloadClipCameraSelectorSignature {\n Element: HTMLDivElement;\n Args: ModalsVideoDownloadClipCameraSelectorArgs;\n}\n\nexport default class ModalsVideoDownloadClipCameraSelector extends Component {\n /**\n * The available cameras options.\n */\n @computed('args.cameras.[]')\n get availableCameras(): DropdownSelectItem[] {\n return (this.args.cameras ?? []).map(({ id, description }) =>\n DropdownSelectItem.create({\n value: id,\n name: description\n })\n );\n }\n}\n\ndeclare module '@glint/environment-ember-loose/registry' {\n export default interface Registry {\n 'Modals::Video::DownloadClip::CameraSelector': typeof ModalsVideoDownloadClipCameraSelector;\n }\n}\n","import { precompileTemplate } from \"@ember/template-compilation\";\nexport default precompileTemplate(\"
\\n \\n \\n \\n
\\n\",{ moduleName: \"customer-site/components/modals/video/download-clip/duration/index.hbs\" })","/* import __COLOCATED_TEMPLATE__ from './index.hbs'; */\nimport Component from '@glimmer/component';\nimport { computed } from '@ember/object';\nimport { inject as service } from '@ember/service';\nimport { NUM_SECONDS_IN_DAY, NUM_SECONDS_IN_HOUR } from 'customer-site/utils/datetime';\nimport DropdownSelectItem from '@adc/ui-components/utils/dropdown-select-item';\n\nimport type ADCIntlService from '@adc/i18n/services/adc-intl';\n\ninterface ModalsVideoDownloadClipDurationArgs {\n durations: number[];\n duration: number;\n disableControls?: boolean;\n 'value-change': (v: string) => void;\n}\n\ninterface ModalsVideoDownloadClipDurationSignature {\n Element: HTMLDivElement;\n Args: ModalsVideoDownloadClipDurationArgs;\n}\n\nexport default class ModalsVideoDownloadClipDuration extends Component {\n @service declare intl: ADCIntlService;\n\n private getReadableDurationText(secondsToParse: number): string {\n return [\n // If this is 24 hours or more.\n ['days', Math.floor(secondsToParse / NUM_SECONDS_IN_DAY)],\n // If this is 1 hour or more but not evenly divisible by a day.\n ['hours', Math.floor((secondsToParse % NUM_SECONDS_IN_DAY) / NUM_SECONDS_IN_HOUR)],\n // If this is 1 minute or more and not evenly divisible by an hour.\n ['minutes', Math.floor((secondsToParse % NUM_SECONDS_IN_HOUR) / 60)],\n // If this is not evenly divisible by a minute.\n ['seconds', secondsToParse % 60]\n ]\n .map(([key, num]: [string, number]) => (num ? this.intl.t(`generic.${key}`, { num }) : undefined))\n .compact()\n .join(' ');\n }\n\n @computed('args.durations.[]')\n get durationItems(): DropdownSelectItem[] {\n return (this.args.durations ?? []).map((value) =>\n DropdownSelectItem.create({\n value: String(value),\n name: this.getReadableDurationText(value)\n })\n );\n }\n}\n\ndeclare module '@glint/environment-ember-loose/registry' {\n export default interface Registry {\n 'Modals::Video::DownloadClip::Duration': typeof ModalsVideoDownloadClipDuration;\n }\n}\n","import { precompileTemplate } from \"@ember/template-compilation\";\nexport default precompileTemplate(\"
\\n \\n \\n \\n
\\n\",{ moduleName: \"customer-site/components/modals/video/download-clip/export-options/index.hbs\" })","/* import __COLOCATED_TEMPLATE__ from './index.hbs'; */\nimport Component from '@glimmer/component';\nimport { computed, action } from '@ember/object';\nimport { inject as service } from '@ember/service';\nimport {\n ExportOptionDirectDownload,\n ExportOptionAddToSavedClips,\n ExportOptionDirectDownloadAddToSavedClips\n} from 'customer-site/components/video/video-player/playback-features/index';\nimport { sentryWithScopeAndError } from '@adc/app-infrastructure/utils/sentry';\nimport { intlPath } from '@adc/i18n/path';\nimport DropdownSelectItem from '@adc/ui-components/utils/dropdown-select-item';\n\nimport type ADCIntlService from '@adc/i18n/services/adc-intl';\n\ninterface ExportOptionsComponentArgs {\n exportOptions?: number[];\n currentValue?: number;\n updateValue?: (v: number) => void;\n disableControls?: boolean;\n}\n\ninterface ExportOptionsComponentSignature {\n Element: HTMLDivElement;\n Args: ExportOptionsComponentArgs;\n}\n\n@intlPath({ path: 'modals/video/download-clip/export-options' })\nexport default class ExportOptionsComponent extends Component {\n @service declare intl: ADCIntlService;\n\n /**\n * The available output options.\n */\n @computed('args.exportOptions')\n get availableOptions() {\n return (this.args.exportOptions ?? []).map((value) =>\n DropdownSelectItem.create({\n value: String(value),\n name: this.getReadableExportOptionText(value)\n })\n );\n }\n\n @action updateValue(v: string) {\n this.args.updateValue?.(Number(v));\n }\n\n /**\n * Converts export option value into readable text.\n * @param {number} exportOption The export option value.\n *\n * @returns {string}\n *\n * @private\n * @instance\n * @memberOf components.modals.video.ClipDownload\n */\n private getReadableExportOptionText(exportOption: number): string {\n switch (exportOption) {\n case ExportOptionDirectDownload:\n return this.intl.t('generic.video.directDownload');\n case ExportOptionAddToSavedClips:\n return this.intl.t('generic.video.addToSavedVideoClips');\n case ExportOptionDirectDownloadAddToSavedClips:\n return this.intl.t('generic.video.directDownloadAddToSavedVideoClips');\n default:\n sentryWithScopeAndError('Undefined Export Option', {}, { feature: 'Clip Upload to Cloud' });\n return 'Undefined Option';\n }\n }\n}\n\ndeclare module '@glint/environment-ember-loose/registry' {\n export default interface Registry {\n 'Modals::Video::DownloadClip::ExportOptions': typeof ExportOptionsComponent;\n }\n}\n","import { precompileTemplate } from \"@ember/template-compilation\";\nexport default precompileTemplate(\"

{{@title}}

\\n

{{@message}}

\\n\\n\",{ moduleName: \"customer-site/components/modals/video/download-clip/warning.hbs\" })","/* import __COLOCATED_TEMPLATE__ from './warning.hbs'; */\nimport templateOnlyComponent from '@ember/component/template-only';\n\nimport type { ModalFooterSignature } from '@adc/ui-components/components/modals/base/footer/modal-footer';\n\nexport interface VideoDownloadClipWarningModalSignature {\n Args: Pick & {\n title: string;\n message: string;\n };\n}\n\nconst VideoDownloadClipWarningModal = templateOnlyComponent();\nexport default VideoDownloadClipWarningModal;\n\ndeclare module '@glint/environment-ember-loose/registry' {\n export default interface Registry {\n 'Modals::Video::DownloadClip::Warning': typeof VideoDownloadClipWarningModal;\n }\n}\n","import { precompileTemplate } from \"@ember/template-compilation\";\nexport default precompileTemplate(\"
\\n
\\n
\\n
\\n \\n
\\n {{t \\'generic.loadingEllipsis\\'}}\\n
\\n
\",{ moduleName: \"customer-site/components/ui/page-blocking-loading-overlay/index.hbs\" })","/* import __COLOCATED_TEMPLATE__ from './index.hbs'; */\nimport templateOnlyComponent from '@ember/component/template-only';\n\nimport './_style.scss';\n\nexport interface UiPageBlockingLoadingOverlaySignature {\n Element: HTMLElement;\n Args: {\n icon?: string;\n title?: string | Promise;\n notification?: string;\n };\n Blocks: {\n default: [];\n };\n}\n\nconst UiPageBlockingLoadingOverlay = templateOnlyComponent();\nexport default UiPageBlockingLoadingOverlay;\n\ndeclare module '@glint/environment-ember-loose/registry' {\n export default interface Registry {\n 'Ui::PageBlockingLoadingOverlay': typeof UiPageBlockingLoadingOverlay;\n }\n}\n","import { precompileTemplate } from \"@ember/template-compilation\";\nexport default precompileTemplate(\"{{! template-lint-disable no-invalid-interactive }}\\n\\n
\\n \\n \\n {{t \\'generic.xOfY\\' x=@page y=@totalPages}}\\n \\n \\n
\\n\\n\",{ moduleName: \"customer-site/components/ui/simple-pagination/index.hbs\" })","/* import __COLOCATED_TEMPLATE__ from './index.hbs'; */\nimport Component from '@glimmer/component';\nimport { action } from '@ember/object';\nimport { timeout, task } from 'ember-concurrency';\n\nimport './_style.scss';\n\ninterface UiSimplePaginationSignature {\n Element: HTMLDivElement;\n Args: {\n page: number;\n totalPages: number;\n changePage: (newPage: number) => void;\n autoHide: boolean;\n };\n}\n\n/**\n * @classdesc\n * A simple pagination control with previous and next page buttons, current page summary, and the ability to auto hide when not interactive.\n */\nexport default class UiSimplePagination extends Component {\n /**\n * A task indicating the component hover is active.\n */\n activeHover = task({ restartable: true }, async () => {\n await timeout(2000);\n });\n\n /**\n * Called to schedule active state hover on/off (if auto hide is enabled).\n */\n @action toggleHover(isActive: boolean): void {\n if (this.args.autoHide) {\n this.activeHover[isActive ? 'perform' : 'cancelAll']();\n }\n }\n}\n\ndeclare module '@glint/environment-ember-loose/registry' {\n export default interface Registry {\n 'Ui::SimplePagination': typeof UiSimplePagination;\n }\n}\n","import { precompileTemplate } from \"@ember/template-compilation\";\nexport default precompileTemplate(\"
\\n
\\n {{#if @onPlayerScreen}}\\n \\n {{else}}\\n {{tc this \\'confidence\\'}}\\n \\n {{/if}}\\n
\\n\\n
\\n {{#unless @onPlayerScreen}}\\n
\\n \\n\\n \\n
\\n {{/unless}}\\n\\n
\\n {{t \\'generic.appliedFiltersCount\\' numFilters=@appliedFiltersCount}}\\n
\\n\\n
\\n {{#if @searchInProgress}}\\n
\\n \\n
\\n\\n {{t \\'generic.searching\\'}}\\n {{/if}}\\n\\n {{t \\'generic.resultsFound\\' resultCount=@resultCount}}\\n
\\n\\n \\n
\\n
\",{ moduleName: \"customer-site/components/video/appearance-search/results-toolbar/index.hbs\" })","/* import __COLOCATED_TEMPLATE__ from './index.hbs'; */\nimport Component from '@glimmer/component';\nimport { intlPath } from '@adc/i18n/path';\n\nimport './_style.scss';\n\ninterface ResultsToolbarSignature {\n Args: {\n appliedFiltersCount: number;\n backToResults: () => void; // go back to the results screen\n confidence: number;\n editSearch: () => void;\n onPlayerScreen: boolean; // if we are viewing this component from the svr player screen\n resultCount: number;\n searchInProgress: boolean;\n setConfidence: (value: number) => void;\n setUsingSmallTileMode: (value: boolean) => void;\n usingSmallTileMode: boolean;\n };\n}\n\n/**\n * @classdesc\n * The toolbar component for the appearance search results page\n */\n@intlPath({ path: 'video/appearance-search/results-toolbar' })\nexport default class ResultsToolbar extends Component {}\n\ndeclare module '@glint/environment-ember-loose/registry' {\n export default interface Registry {\n 'Video::AppearanceSearch::ResultsToolbar': typeof ResultsToolbar;\n }\n}\n","import { precompileTemplate } from \"@ember/template-compilation\";\nexport default precompileTemplate(\"
\\n
\\n
{{t \\'generic.search\\'}}
\\n \\n
\\n
\\n
\\n \\n \\n \\n \\n {{#if this.appearanceFilterEnabled}}\\n {{#each this.appearanceSections as |appearanceSection|}}\\n {{#if appearanceSection.enabled}}\\n
\\n \\n \\n <:value>\\n {{#unless (eq this.selectedOptions.length 0)}}\\n
{{this.selectedOptions.length}}
\\n {{/unless}}\\n \\n \\n
\\n
\\n
\\n
\\n {{#each appearanceSection.classifiers as |classifier|}}\\n

{{classifier.title}}

\\n
\\n {{#each classifier.options as |option|}}\\n \\n {{/each}}\\n
\\n {{/each}}\\n
\\n {{t \\'generic.remove\\'}}\\n
\\n
\\n
\\n {{/if}}\\n {{/each}}\\n {{else}}\\n \\n {{tc this \\'usePlusIcon\\'}}\\n \\n {{/if}}\\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n
\\n
\\n
\\n \\n \\n
\\n
\",{ moduleName: \"customer-site/components/video/appearance-search/search-sidebar/index.hbs\" })","/* import __COLOCATED_TEMPLATE__ from './index.hbs'; */\nimport './_style.scss';\nimport Component from '@glimmer/component';\nimport { tracked } from '@glimmer/tracking';\nimport { action, computed } from '@ember/object';\nimport { inject as service } from '@ember/service';\nimport {\n AttributeTypeEnum,\n ClassifierTypeEnum,\n ColorEnum,\n GlassesEnum,\n VehicleTypeEnum\n} from 'customer-site/enums/AttributeSearch';\nimport { EmberVideoAppearanceSearchResults } from 'customer-site/enums/CustomerPageUrl';\nimport { NUM_MILLISECONDS_IN_DAY } from 'customer-site/utils/datetime';\nimport { intlPath } from '@adc/i18n/path';\nimport SimpleListItem from '@adc/ui-components/components/simple-list/list-item';\nimport CheckboxTreeItem, { SELECTED, UNSELECTED } from '@adc/ui-components/utils/checkbox-tree-item';\nimport DropdownActionItem from '@adc/ui-components/utils/dropdown-action-item';\n\nimport type { Registry as ServiceRegistry } from '@ember/service';\nimport './_style.scss';\nimport type Camera from 'customer-site/models/video/devices/camera';\n\ninterface AppearanceSearchSidebarSignature {\n Element: HTMLDivElement;\n Args: {\n cameras: Camera[] | null;\n closeThis: () => void;\n endDate?: Date;\n startDate?: Date;\n selectedCameras?: string[];\n selectedOptions?: SelectedOption[];\n };\n}\n\nconst AppearanceGroupElement = '.appearance-group';\n\n// Data for displaying the various appearance sections/classifiers\ntype AppearanceSection = {\n enabled: boolean;\n type: AttributeTypeEnum;\n minimized: boolean;\n headerItems: SimpleListItem[];\n classifiers: {\n title: string;\n type: ClassifierTypeEnum;\n options: {\n name: string;\n type: number;\n isSelected: boolean;\n }[];\n }[];\n};\n\n// All of the classifier attributes available to search for\ntype AllAttributeClassifiers = {\n name: string;\n icon: string;\n type: number;\n classifiers: AttributeClassifier[];\n}[];\n\n// An individual classifier with attributes available to search for. Examples of classifier might be Car Type, Car Color, Outfit Top, etc\ntype AttributeClassifier = {\n name: string;\n type: number;\n options: AttributeOption[];\n};\n\n// An option available to search for.\ntype AttributeOption = {\n name: string;\n type: number;\n};\n\n// The response data received by the getAttributes API\ntype AttributesResponse = {\n value?: {\n type: AttributeTypeEnum;\n classifiers: {\n type: ClassifierTypeEnum;\n mask?: number;\n glasses?: GlassesEnum[];\n vehicles?: VehicleTypeEnum[];\n colors?: ColorEnum[];\n }[];\n }[];\n};\n\n// An option which is selected by the user\nexport type SelectedOption = {\n attributeType: AttributeTypeEnum;\n classifierType: ClassifierTypeEnum;\n optionType: number;\n};\n\n/**\n * @classdesc\n * The sidebar for the doing an appearance search\n */\n@intlPath({ path: 'video.appearance-search.search-sidebar' })\nexport default class AppearanceSearchSidebar extends Component {\n @service declare intl: ServiceRegistry['adc-intl'];\n @service declare navigation: ServiceRegistry['navigation'];\n @service declare ajax: ServiceRegistry['ajax'];\n\n constructor(owner: unknown, args: AppearanceSearchSidebarSignature['Args']) {\n super(owner, args);\n\n this.resetOptions();\n }\n\n /**\n * If the appearance filter popover (vehicle/person) is open.\n */\n @tracked appearancePopoverIsOpen = false;\n\n /**\n * Information about all the attribute classifiers\n */\n @tracked allAttributeClassifiers: AllAttributeClassifiers = [];\n\n /**\n * If the dropdown for selecting cameras is open\n */\n @tracked camerasDropdownIsOpen = false;\n\n /**\n * The appearance sections (vehicle/person) that are currently enabled\n */\n @tracked enabledAppearanceSections: AttributeTypeEnum[] = [];\n\n /**\n * The appearance sections (vehicle/person) that are currently minimized\n */\n @tracked minimizedAppearanceSections: AttributeTypeEnum[] = [];\n\n /**\n * Which cameras are selected (their globalDeviceId)\n */\n @tracked selectedCameras: string[] = [];\n\n /**\n * Options that the user has selected\n */\n @tracked selectedOptions: SelectedOption[] = [];\n\n /**\n * The selected start date\n */\n @tracked selectedStartDate: Date = this.getDefaultStartDate();\n\n /**\n * The selected end date\n */\n @tracked selectedEndDate: Date = new Date();\n\n /**\n * If the appearance filter is enabled (atleast one of the appearance sections is enabled)\n */\n @computed('enabledAppearanceSections.length')\n get appearanceFilterEnabled(): boolean {\n return this.enabledAppearanceSections.length > 0;\n }\n\n /**\n * The appearance sections and their info\n */\n @computed('allAttributeClassifiers', 'enabledAppearanceSections', 'minimizedAppearanceSections', 'selectedOptions')\n get appearanceSections(): AppearanceSection[] {\n const { allAttributeClassifiers } = this;\n\n return allAttributeClassifiers.map((section) => {\n return {\n type: section.type,\n enabled: this.enabledAppearanceSections.includes(section.type),\n minimized: this.minimizedAppearanceSections.includes(section.type),\n headerItems: [\n new SimpleListItem({\n description: section.name,\n icon: section.icon\n })\n ],\n classifiers: section.classifiers.map((classifier) => {\n return {\n title: classifier.name,\n type: classifier.type,\n options: classifier.options.map((option) => {\n return {\n name: option.name,\n type: option.type,\n isSelected: this.optionIsSelected(section.type, classifier.type, option.type)\n };\n })\n };\n })\n };\n });\n }\n\n /**\n * The dropdown items for the sections after the user hits the + button\n */\n @computed('appearanceSections')\n get appearanceDropdownItems(): DropdownActionItem[] {\n return this.appearanceSections.map((section) => {\n return DropdownActionItem.create({\n name: section.headerItems[0].description?.toString(),\n action: () => this.selectAppearanceSectionType(section.type)\n });\n });\n }\n\n /**\n * The dropdown cameras you can select from\n */\n @computed('args.{cameras,selectedCameras}')\n get camerasDropdownItems(): CheckboxTreeItem[] {\n const { cameras, selectedCameras } = this.args;\n\n if (!cameras) {\n return [];\n }\n\n const subitems = cameras.map((camera) => {\n let state = SELECTED;\n\n // if selectedCameras arg is passed in, lets set the state based on that, otherwise leave the page on the\n // default behavior, which is all cameras selected\n if (selectedCameras) {\n state = selectedCameras.includes(camera.globalDeviceId || '') ? SELECTED : UNSELECTED;\n }\n\n return CheckboxTreeItem.create({\n name: camera.description,\n value: camera.globalDeviceId,\n state\n });\n });\n\n return [\n CheckboxTreeItem.create({\n name: this.intl.t('generic.devices.cameras'),\n isSelectable: false,\n showAllNoneSelectors: true,\n subitems\n })\n ];\n }\n\n /**\n * Text for displaying how many cameras are selected\n */\n @computed('selectedCameras.length', 'args.cameras.length')\n get camerasSelectedText(): string {\n const { args, intl, selectedCameras } = this;\n\n if (selectedCameras.length === args.cameras?.length) {\n return intl.t('generic.allSelected');\n }\n\n return intl.t('generic.video.camerasSelected', {\n num: selectedCameras.length\n });\n }\n\n /**\n * If the search button is enabled\n */\n @computed('enabledAppearanceSections.length', 'selectedOptions.length', 'selectedCameras.length')\n get searchIsEnabled(): boolean {\n return (\n this.enabledAppearanceSections.length > 0 &&\n this.selectedOptions.length > 0 &&\n this.selectedCameras.length > 0\n );\n }\n\n /**\n * Gets the default start date, 24 hours ago\n */\n private getDefaultStartDate(): Date {\n return new Date(Date.now() - NUM_MILLISECONDS_IN_DAY);\n }\n\n /**\n * If the option passed in is selected by the user\n */\n private optionIsSelected(\n attributeType: AttributeTypeEnum,\n classifierType: ClassifierTypeEnum,\n optionType: number\n ): boolean {\n return this.selectedOptions.some(\n (o) =>\n o.attributeType === attributeType && o.classifierType === classifierType && o.optionType === optionType\n );\n }\n\n /**\n * Changing which cameras are selected\n */\n @action\n changeSelectedCameras(newItems: CheckboxTreeItem[]): void {\n const filteredSelected = newItems[0].subitems.filter((camera) => camera.state === SELECTED);\n this.selectedCameras = filteredSelected.map((camera) => camera.value);\n }\n\n /**\n * Changing the selected date range\n */\n @action\n changeSelectedDateRange(startEndDate: { startDate: Date; endDate: Date }): void {\n this.selectedStartDate = startEndDate.startDate;\n this.selectedEndDate = startEndDate.endDate;\n }\n\n /**\n * Disabling the appearance filter\n */\n @action\n disableAppearanceFilter(): void {\n this.enabledAppearanceSections = [];\n this.selectedOptions = [];\n }\n\n /**\n * Navigates to the appearance search results page\n */\n @action\n goToAppearanceSearchResults(): void {\n this.navigation.transitionToRouteId(EmberVideoAppearanceSearchResults, {\n queryParams: {\n selectedOptions: JSON.stringify(this.selectedOptions),\n startDate: this.selectedStartDate.toISOString(),\n endDate: this.selectedEndDate.toISOString(),\n cameraId: JSON.stringify(this.selectedCameras)\n }\n });\n }\n\n /**\n * Initialize various properties\n */\n @action\n async initialize(): Promise {\n const { args } = this,\n { selectedCameras, startDate, endDate, selectedOptions } = args;\n\n const attributesResponse = (await this.ajax.apiRequest(\n 'video/attribute-search/getAttributes'\n )) as AttributesResponse;\n\n this.allAttributeClassifiers = this.convertGettAttributesResponseToAllAttributeClassifiers(attributesResponse);\n\n if (startDate) {\n this.selectedStartDate = startDate;\n }\n\n if (endDate) {\n this.selectedEndDate = endDate;\n }\n\n if (selectedOptions) {\n this.selectedOptions = selectedOptions;\n this.enabledAppearanceSections = selectedOptions.map((option) => option.attributeType);\n }\n\n if (selectedCameras) {\n this.selectedCameras = selectedCameras;\n }\n }\n\n /**\n * Resets the options to their defaults\n */\n @action\n resetOptions(): void {\n this.selectedOptions = [];\n this.enabledAppearanceSections = [];\n this.selectedStartDate = this.getDefaultStartDate();\n this.selectedEndDate = new Date();\n // the page starts with all cameras selected\n this.selectedCameras = this.args.cameras?.map((camera) => camera.globalDeviceId || '') || [];\n this.minimizedAppearanceSections = [];\n }\n\n /**\n * Selects the appearance section for enabling\n */\n @action\n selectAppearanceSectionType(type: AttributeTypeEnum): void {\n this.enabledAppearanceSections = [...this.enabledAppearanceSections, type];\n this.appearancePopoverIsOpen = false;\n }\n\n /**\n * Toggle if the option is selected\n */\n @action\n toggleOption(\n attributeType: AttributeTypeEnum,\n classifierType: ClassifierTypeEnum,\n optionType: number,\n isSelected: boolean\n ): void {\n if (isSelected) {\n this.selectedOptions = this.selectedOptions.filter(\n (o) =>\n !(\n o.attributeType === attributeType &&\n o.classifierType === classifierType &&\n o.optionType === optionType\n )\n );\n } else {\n this.selectedOptions = [...this.selectedOptions, { attributeType, optionType, classifierType }];\n }\n }\n\n /**\n * Toggles if the section is minimized\n */\n @action\n toggleSectionMinimized(type: AttributeTypeEnum): void {\n if (this.minimizedAppearanceSections.includes(type)) {\n this.minimizedAppearanceSections = this.minimizedAppearanceSections.filter((t) => t !== type);\n\n // Focus back on the appearance group since we are likely scrolled down too far when minimizing\n const appearanceGroupElement = document.querySelector(AppearanceGroupElement) as HTMLElement;\n appearanceGroupElement?.focus();\n } else {\n this.minimizedAppearanceSections = [...this.minimizedAppearanceSections, type];\n }\n }\n\n /**\n * Converts the result of the getAttributes request and converts it into the AllAttributeClassifiers object we use\n */\n private convertGettAttributesResponseToAllAttributeClassifiers(\n attributesResponse: AttributesResponse\n ): AllAttributeClassifiers {\n const allClassifiers: AllAttributeClassifiers = [];\n\n if (!attributesResponse.value) {\n return allClassifiers;\n }\n\n for (let i = 0; i < attributesResponse.value.length; i++) {\n const section = attributesResponse.value[i];\n allClassifiers[i] = {\n name: this.getAttributeTypeEnumName(section.type),\n icon: this.getAttributeTypeEnumIcon(section.type),\n type: section.type,\n classifiers: []\n };\n const classifiers = section.classifiers;\n\n for (let j = 0; j < classifiers.length; j++) {\n const classifierInfo = classifiers[j];\n\n const newClassifier: AttributeClassifier = {\n name: this.getClassifierTypeEnumName(classifierInfo.type),\n type: classifierInfo.type,\n options: []\n };\n\n switch (classifierInfo.type) {\n case ClassifierTypeEnum.Mask:\n // mask is a boolean rather than an array, like the others\n newClassifier.options.push({\n name: this.intl.tc(this, 'classifiers.mask'),\n // we dont currently have an enum for mask so just using 1 for the moment\n // todo should fix this in VID-81966\n type: 1\n });\n break;\n case ClassifierTypeEnum.Glasses:\n if (classifierInfo.glasses) {\n newClassifier.options = classifierInfo.glasses.map((type: number) => {\n return {\n name: this.getGlassesEnumName(type),\n type\n };\n });\n }\n break;\n case ClassifierTypeEnum.VehicleType:\n if (classifierInfo.vehicles) {\n newClassifier.options = classifierInfo.vehicles.map((type: number) => {\n return {\n name: this.getVehicleTypeEnumName(type),\n type\n };\n });\n }\n break;\n case ClassifierTypeEnum.OutfitTop:\n case ClassifierTypeEnum.OutfitBottom:\n case ClassifierTypeEnum.VehicleColor:\n if (classifierInfo.colors) {\n newClassifier.options = classifierInfo.colors.map((type: number) => {\n return {\n name: this.getColorEnumName(type),\n type\n };\n });\n }\n break;\n }\n\n allClassifiers[i].classifiers[j] = newClassifier;\n }\n }\n\n return allClassifiers;\n }\n\n /**\n * Gets the resource string for the attribute type\n */\n private getAttributeTypeEnumName(type: AttributeTypeEnum): string {\n const { intl } = this;\n\n const attributeTypeString = {\n [AttributeTypeEnum.Person]: 'person',\n [AttributeTypeEnum.Vehicle]: 'vehicle'\n }[type];\n\n return intl.t(`generic.video.objectDetection.${attributeTypeString}`);\n }\n\n /**\n * Gets the icon for the attribute type\n */\n private getAttributeTypeEnumIcon(type: AttributeTypeEnum): string {\n return {\n [AttributeTypeEnum.Person]: 'user',\n [AttributeTypeEnum.Vehicle]: 'car'\n }[type];\n }\n\n /**\n * Gets the resource string for the classifier type\n */\n private getClassifierTypeEnumName(type: ClassifierTypeEnum): string {\n const { intl } = this;\n\n const string = {\n [ClassifierTypeEnum.OutfitBottom]: 'outfitBottom',\n [ClassifierTypeEnum.OutfitTop]: 'outfitTop',\n [ClassifierTypeEnum.Glasses]: 'glasses',\n [ClassifierTypeEnum.Mask]: 'mask',\n [ClassifierTypeEnum.VehicleColor]: 'color',\n [ClassifierTypeEnum.VehicleType]: 'type'\n }[type];\n\n return intl.tc(this, `classifiers.${string}`);\n }\n\n /**\n * Gets the resource string for the color enum\n */\n private getColorEnumName(type: ColorEnum): string {\n const { intl } = this;\n\n const colorString = {\n [ColorEnum.Black]: 'black',\n [ColorEnum.Blue]: 'blue',\n [ColorEnum.Brown]: 'brown',\n [ColorEnum.Gray]: 'gray',\n [ColorEnum.Green]: 'green',\n [ColorEnum.Gold]: 'gold',\n [ColorEnum.Orange]: 'orange',\n [ColorEnum.Red]: 'red',\n [ColorEnum.White]: 'white',\n [ColorEnum.Yellow]: 'yellow'\n }[type];\n\n return intl.t(`generic.colors.${colorString}`);\n }\n\n /**\n * Gets the resource string for the glasses enum\n */\n private getGlassesEnumName(type: GlassesEnum): string {\n const { intl } = this;\n\n const glassesString = {\n [GlassesEnum.Glasses]: 'glasses',\n [GlassesEnum.NoGlasses]: 'noglasses',\n [GlassesEnum.Sunglasses]: 'sunglasses'\n }[type];\n\n return intl.tc(this, `glasses.${glassesString}`);\n }\n\n /**\n * Gets the resource string for the vehicle type enum\n */\n private getVehicleTypeEnumName(type: VehicleTypeEnum): string {\n const { intl } = this;\n\n const vehicleString = {\n [VehicleTypeEnum.Bus]: 'bus',\n [VehicleTypeEnum.Car]: 'car',\n [VehicleTypeEnum.Pickup]: 'pickup',\n [VehicleTypeEnum.Suv]: 'suv',\n [VehicleTypeEnum.Truck]: 'truck',\n [VehicleTypeEnum.Van]: 'van'\n }[type];\n\n return intl.tc(this, `vehicles.${vehicleString}`);\n }\n}\n\ndeclare module '@glint/environment-ember-loose/registry' {\n export default interface Registry {\n 'Video::AppearanceSearch::SearchSidebar': typeof AppearanceSearchSidebar;\n }\n}\n","import Component from '@glimmer/component';\nimport { action, computed, get } from '@ember/object';\nimport { inject as service } from '@ember/service';\nimport { NotOperatorSite } from 'customer-site/components/video/clips/video-modal/index';\nimport VideoClipsModal from 'customer-site/components/video/clips/video-modal/index';\n\nimport './_style.scss';\n\n/**\n * Creates and returns a time range string from the instance items.\n *\n * @param {Array} items the array of items to find the time range of (such as visual verification items or clip items)\n * @param {String} path the path to the timestamp property of the item\n * @param {Boolean} useDateTime boolean for using DateTime format (e.g. 11/11/21, 11:23 AM) or Time format (11:23 AM)\n *\n * @returns {String}\n *\n * @private\n * @instance\n * @memberof components.video.clips.ClipDisplay.BaseClipDisplay\n */\nexport function getTimeRange(items, path, useDateTime) {\n const { intl, contextManager } = this;\n\n return [items.lastObject, items.length > 1 ? items.firstObject : undefined]\n .compact()\n .map((item) =>\n intl.formatDateTz(get(item, path), {\n format: useDateTime ? 'shortDateTimeFormat' : 'shortTimeFormat',\n timeZone: item.showPreferredTimezone ? contextManager.identityModel.preferredTimezone : intl.timeZone\n })\n )\n .join(' - ');\n}\n\n/**\n * Plays the collection of media items, beginning with the passed media (in place).\n *\n * @param {classes.video.clips.helpers.MediaItem} media The media to play.\n *\n * @private\n * @instance\n * @memberof components.video.clips.ClipDisplay.BaseClipDisplay\n */\nexport function playMediaItems(mediaItem) {\n const media = this.media.rejectBy('isDeleted');\n\n this.modals.showModal(VideoClipsModal, {\n media,\n selectedIndex: media.indexOf(mediaItem),\n operatorSiteEnum: NotOperatorSite\n });\n}\n\n/**\n * @classdesc\n * A collection of media items, grouped by the day they were captured.\n *\n * @class components.video.clips.ClipDisplay.BaseClipDisplay\n *\n * @param {EmberArray} media The media to render within this day.\n */\nexport default class BaseClipDisplay extends Component {\n @service intl;\n @service modals;\n @service contextManager;\n\n /**\n * The sorted clips to display.\n *\n * @type {EmberArray}}\n */\n @computed('args.media')\n get media() {\n return (this.args.media || []).sortBy('model.timestamp').reverse();\n }\n\n /**\n * The textual representation of the day this media was captured.\n *\n * @type {String}\n */\n @computed('args.media')\n get displayDate() {\n const { intl, contextManager } = this,\n [media] = this.args.media;\n\n if (media.isToday) {\n return intl.t('generic.today');\n }\n\n return intl.formatDateTz(media.model.timestamp, {\n weekday: 'long',\n month: 'short',\n day: 'numeric',\n year: 'numeric',\n timeZone: media.showPreferredTimezone ? contextManager.identityModel.preferredTimezone : intl.timeZone\n });\n }\n\n /**\n * The textual representation of the time period the media was captured.\n *\n * @type {String}\n */\n @computed('args.media', 'contextManager.identityModel.preferredTimezone')\n get dayTimeRange() {\n return getTimeRange.call(this, this.args.media, 'model.timestamp', false);\n }\n\n /**\n * Opens the video player modal for the passed media.\n *\n * @param {classes.video.clips.helpers.MediaItem} mediaItem The media to play.\n */\n @action playMediaItem(mediaItem) {\n return playMediaItems.call(this, mediaItem);\n }\n}\n","import Component from '@glimmer/component';\n\nimport './_style.scss';\n\nexport default class BasePlayableClipComponent extends Component {}\n","import { precompileTemplate } from \"@ember/template-compilation\";\nexport default precompileTemplate(\"{{! @glint-nocheck: types are not compatible, please delete this comment and fix issues. }}\\n{{#let this.layoutControl.layoutProperties as |layoutProps|}}\\n \\n \\n \\n
\\n {{#if this.showTimeoutMessage}}\\n \\n \\n

{{tc this \\'timeoutMessage\\' minutes=this.centralStationLiveViewDuration}}

\\n
\\n
\\n {{else}}\\n {{#if this.useStreamingToolbar}}\\n \\n \\n \\n {{/if}}\\n {{!-- This section is always in dark mode when in theater or full screen mode - the theater experience ;) --}}\\n
\\n
\\n \\n \\n \\n\\n \\n {{#if this.noSupportedCameras}}\\n
\\n
\\n \\n {{#if this.model.videoStreamingPermissions.showAddCameraLink}}\\n

{{t \\'generic.video.servicePackageIncludesVideoMonitoring\\'}}

\\n \\n {{else}}\\n

{{tc this \\'noCamerasAvailable\\'}}

\\n {{/if}}\\n
\\n
\\n {{else if this.noActiveCameras}}\\n
\\n
\\n
{{t \\'generic.noResults\\'}}
\\n
\\n
\\n {{else}}\\n
\\n \\n {{#if this.showPagination}}\\n \\n {{/if}}\\n
\\n {{/if}}\\n\\n
\\n\\n \\n\\n \\n
\\n
\\n {{/if}}\\n
\\n \\n \\n \\n{{/let}}\",{ moduleName: \"customer-site/components/video/live-video/index.hbs\" })","/* import __COLOCATED_TEMPLATE__ from './index.hbs'; */\nimport { computed, action, set } from '@ember/object';\nimport { equal } from '@ember/object/computed';\nimport { inject as service } from '@ember/service';\nimport { task, timeout } from 'ember-concurrency';\nimport { PageChange } from 'customer-site/enums/TrackedEvent';\nimport { getDeviceIdFromGlobalId } from 'customer-site/utils/general';\nimport { POST } from '@adc/ajax/services/adc-ajax';\nimport { intlPath } from '@adc/i18n/path';\nimport DropdownSelectItem, { SELECTED, UNSELECTED } from '@adc/ui-components/utils/dropdown-select-item';\nimport { VideoAddNewDevice } from '../../../enums/CustomerPageUrl';\nimport { StreamUsage } from '../../../enums/StreamUsage';\nimport {\n setCameraIsPlayingProperty,\n setCameraProperties\n} from '../video-streaming/video-streaming-features/camera-items';\nimport VideoStreamingFeatures, {\n addLocationGroupsToCameraGroups,\n setInitialSetupDone,\n updateCameraGroupAndCamera,\n setActiveCameras,\n VideoStreamingFeaturesType\n} from '../video-streaming/video-streaming-features/index';\n\nimport './_style.scss';\nimport type ArrayProxy from '@ember/array/proxy';\nimport type { Registry as ServiceRegistry } from '@ember/service';\nimport type LocationModel from 'customer-site/models/enterprise/locations/location';\nimport type CameraGroup from 'customer-site/models/video/camera-group';\nimport type Camera from 'customer-site/models/video/devices/camera';\nimport type DewarpConfig from 'customer-site/models/video/dewarp-config';\nimport type OnvifPtzPreset from 'customer-site/models/video/onvif-ptz-preset';\nimport type VideoStreamingPermissionsCollection from 'customer-site/models/video/permissions/video-streaming-permissions-collection';\nimport type { ResolvedBaseLiveViewModel } from 'customer-site/video/live-view/base-live-view-route';\n\n// The default max number of videos per page to display. We want to have a higher default for commercial users\nconst defaultMaxVideosPerPageAutoViewCommercial = 9,\n defaultMaxVideosPerPageAutoViewResidential = 4;\n\n/**\n * Time to wait between updating viewing session data in the DB during an operator session.\n */\nconst UpdateOperatorViewingSessionFrequencyMs = 5000;\n\n/**\n * Uses the camera model's isPlaying property to obtain a set of (deviceId, playerUsage) pairs\n * representing the collection of cameras that are actively viewable and streaming on our live\n * view page. isPlaying gets updated when individual players begin/stop playing as well as when a\n * user action would result in a video player being destroyed due to moving offscreen (e.g. grid page\n * change or layout change).\n *\n */\nfunction getCurrentlyStreamingPlayers(this: VideoStreamingFeatures): Record {\n const currentlyStreamingPlayers: Record = {};\n\n this.activeCameras?.filterBy('isPlaying').forEach((camera: Camera) => {\n currentlyStreamingPlayers[getDeviceIdFromGlobalId(camera.globalDeviceId!)] =\n camera.usageProtocolMapping[this.playerType!];\n });\n\n return currentlyStreamingPlayers;\n}\n\n/**\n * @classdesc\n *\n * Component that represents a live video page.\n */\n@intlPath({ path: 'video.live-video' })\nexport default class LiveVideo extends VideoStreamingFeatures {\n @service declare media: ADCResponsiveMediaService;\n @service('video.onvif-ptz-preset-manager')\n declare onvifPtzPresetManager: ServiceRegistry['video/onvif-ptz-preset-manager'];\n\n /** @override */\n get componentType(): number {\n return VideoStreamingFeaturesType.Live;\n }\n\n /** @override */\n playerType = StreamUsage.LiveView;\n\n /** @override */\n playerTypeString = 'Live';\n\n /**\n * Can the operator site NOT do in-browser audio streams and uploads because we failed a VVCLIP health check?\n */\n cannotDoBrowserUploadsForOperatorSite = false;\n\n /** @override */\n showHdButtonFn = (cameras: Camera[]): boolean => cameras.isAny('liveViewHdToggleEnabled');\n\n /**\n * The live video model info passed in.\n */\n declare model: ResolvedBaseLiveViewModel;\n\n /**\n * Are we on a visual verification or Remote Video Monitoring Console page?\n */\n declare isOperatorSite: boolean;\n\n /**\n * Is this an operator portal with two-way talkdown?\n */\n declare hasTwoWayTalkdownInOperatorPortalPermissions: boolean;\n\n /**\n * Has there been a recent operator event in the past 15 minutes?\n */\n declare systemHasRecentOperatorEvent: boolean;\n\n /*\n * The time (in minutes) an operator can view live video after an alarm or Remote Video Monitoring event.\n */\n declare centralStationLiveViewDuration: number;\n\n // region Overridden Component Hooks\n\n /**\n * Further component specific processing to do after camera items have been set.\n *\n * @function\n * @override\n */\n afterCameraItemsProcessing(): void {\n // For each oesp controller, detach connected oesp players\n this.playbackStateControllers?.forEach((controller) => controller.resetPlayers());\n\n // Reset the controllers\n set(this, 'playbackStateControllers', []);\n set(this, 'moreThanOneCameraTimedOut', false);\n }\n\n // endregion\n\n // region Camera Groups\n\n /**\n * The items for the camera group dropdown.\n */\n @computed('cameraGroups', 'cameraGroupId')\n get cameraGroupItems(): DropdownSelectItem[] | undefined {\n return this.cameraGroups?.map((cameraGroup) =>\n DropdownSelectItem.create({\n name: cameraGroup.name,\n value: cameraGroup.id,\n state: cameraGroup.id === this.cameraGroupId ? SELECTED : UNSELECTED\n })\n );\n }\n\n // endregion\n\n // region OperatorSite\n\n /**\n * Should we display the operator session timeout message?\n *\n * This occurs if the monitoring station live view time limit has been reached.\n * This time window depends on the CentralStationLiveViewDuration dealer parameter.\n * This is after the last alarm for Visual Verification, or after the last Remote Video Monitoring event for Remote Video Monitoring Console.\n */\n @computed('isOperatorSite', 'systemHasRecentOperatorEvent')\n get showTimeoutMessage(): boolean {\n return this.isOperatorSite && !this.systemHasRecentOperatorEvent;\n }\n\n /**\n * Periodically update operator viewing session data in the DB.\n */\n updateOperatorViewingSessionData = task({ restartable: true }, async () => {\n for (;;) {\n await timeout(UpdateOperatorViewingSessionFrequencyMs);\n const currentlyStreamingPlayers = getCurrentlyStreamingPlayers.call(this);\n\n // No need to save viewing session data if no players are actually streaming\n if (Object.keys(currentlyStreamingPlayers).length) {\n await this.ajax.apiRequest(\n 'operatorSite/operatorSiteStream/saveLiveSessionData',\n undefined,\n currentlyStreamingPlayers,\n POST\n );\n }\n }\n });\n\n // endregion\n\n // region Toolbar\n\n /**\n * Should we use the video streaming toolbar component?\n */\n @computed('initialSetupDone', 'noSupportedCameras')\n get useStreamingToolbar(): boolean {\n return this.initialSetupDone && !this.noSupportedCameras;\n }\n\n // endregion\n\n // region Pages\n\n /**\n * Whether to disable the previous page button.\n */\n @equal('page', 1)\n declare previousButtonDisabled: boolean;\n\n /**\n * Whether to disable the next page button.\n */\n @equal('page', 'totalPages')\n declare nextButtonDisabled: boolean;\n\n // endregion\n\n // region Synced Streaming Values\n\n /**\n * If there 2 or more cameras that are in a timed out state. This variable only exists on the live video component as the timeout behavior functions differently\n * on playback-features (sd/svr)\n */\n moreThanOneCameraTimedOut = false;\n\n // endregion\n\n //#region Render Modifier Actions\n\n //#endregion\n\n // region Toolbar Actions\n\n /**\n * Sets the activeCameras list\n */\n @action\n setActiveCameras(newActiveCameras: Camera[]): void {\n setActiveCameras.call(this, newActiveCameras);\n }\n\n // endregion\n\n // region Footer Functions\n\n /**\n * Handles a user clicking a button to go to the previous or next page.\n *\n * @override\n */\n @action\n changePage(newPage: number): void {\n this.stats.logEvent(PageChange);\n\n // Tell the child component to leave expanded view.\n set(this, 'page', newPage);\n this.layoutControl.setExpandedCameraIndex(undefined);\n }\n\n // endregion\n\n // region Transition Functions\n\n /**\n * Transitions to the manage camera groups page.\n */\n @action\n transitionToManagePage(): void {\n // TODO: This ignore is an existing deprecation that must be refactored, do not copy this usage\n // eslint-disable-next-line @adc/ember/no-context-manager-transition\n this.contextManager.transitionToRouteId(this.manageGroupsRouteId);\n }\n\n /**\n * Transitions to the add new camera page.\n */\n @action\n transitionToAddVideoDevice(): void {\n // TODO: This ignore is an existing deprecation that must be refactored, do not copy this usage\n // eslint-disable-next-line @adc/ember/no-context-manager-transition\n this.contextManager.transitionToRouteId(VideoAddNewDevice);\n }\n\n // endregion\n\n /**\n * Gets things ready once data is loaded.\n *\n * @param cameraGroups All the camera groups available in the context.\n * @param cameras All the cameras available in the context.\n * @param cannotDoBrowserUploadsForOperatorSite Can the operator site NOT do in-browser audio streams and uploads because we failed a VVCLIP health check?\n * @param locationCameraGroupInfos Corresponds to the simple location models for this group (or null for single-system context)\n * @param videoStreamingPermissions An object containing live-view-specific permission values.\n * @param onvifPtzPresets All the onvif ptz presets available in the context.\n */\n @action\n dataLoaded({\n cameraGroups,\n cameras,\n cannotDoBrowserUploadsForOperatorSite,\n videoStreamingPermissions,\n locationCameraGroupInfos,\n onvifPtzPresets\n }: {\n cameraGroups: CameraGroup[];\n cameras: Camera[];\n cannotDoBrowserUploadsForOperatorSite: boolean;\n dewarpConfigs: ArrayProxy;\n videoStreamingPermissions: VideoStreamingPermissionsCollection;\n locationCameraGroupInfos: LocationModel[];\n onvifPtzPresets: ArrayProxy;\n }): void {\n // We clone the camera groups array so we can push the all cameras group to it;\n // we explicitly sort it since Ember doesn't know to keep it sorted by order if we change any camera group orders.\n const sortedCameraGroups = cameraGroups.sortBy('order'),\n liveViewCameras = cameras || [],\n liveViewCamerasCount = liveViewCameras.length,\n { isCommercial, isEnterprise, isOperatorSite, layoutControl } = this;\n\n // If the user has no live streaming cameras, display a message and a link to the add camera page.\n if (liveViewCamerasCount === 0) {\n setInitialSetupDone.call(this);\n set(this, 'noSupportedCameras', true);\n return;\n }\n\n // If we're in Visual Verification or Remote Video Monitoring Console context we want excluded cameras to be unselectable in camera dropdowns\n if (isOperatorSite) {\n const { isEscalatedEvents } = this.contextManager.identityModel;\n\n // If this session supports two-way talkdown, always request microphone permissions on page load to prompt reps to accept them.\n if (videoStreamingPermissions.hasTwoWayTalkdownInOperatorPortalPermissions) {\n navigator.mediaDevices.getUserMedia({ audio: true, video: false });\n }\n\n cameras.forEach(function (camera) {\n set(\n camera,\n 'selectableInDropdown',\n isEscalatedEvents ? !camera.excludedFromEscalatedEvents : !camera.excludedFromVisualVerification\n );\n });\n\n if (cannotDoBrowserUploadsForOperatorSite) {\n this.notificationManager.addWarning(this.intl.t('components.video.live-video.clippyHealthCheckFailed'));\n }\n\n // Tasks that run infinitely can break tests\n if (!this.envSettings.isTestEnvironment()) {\n this.updateOperatorViewingSessionData.perform();\n }\n }\n\n addLocationGroupsToCameraGroups.call(this, locationCameraGroupInfos, sortedCameraGroups, cameras);\n\n layoutControl.makeSureLayoutIsSetCorrectly(cameras.length, true);\n\n if (!layoutControl.maxVideosPerPageAutoView) {\n set(\n layoutControl,\n 'maxVideosPerPageAutoView',\n isCommercial || isEnterprise\n ? defaultMaxVideosPerPageAutoViewCommercial\n : defaultMaxVideosPerPageAutoViewResidential\n );\n }\n\n set(this, 'cameraGroups', sortedCameraGroups);\n set(this, 'cameras', cameras);\n set(this, 'canEditCameraGroups', videoStreamingPermissions.canEditCameraGroups && !isOperatorSite);\n set(this, 'cannotDoBrowserUploadsForOperatorSite', cannotDoBrowserUploadsForOperatorSite);\n set(this, 'canViewManageCameraGroups', videoStreamingPermissions.canViewManageCameraGroups && !isOperatorSite);\n set(this, 'centralStationLiveViewDuration', videoStreamingPermissions.centralStationLiveViewDuration);\n set(this, 'moreThanOneSupportedCamera', liveViewCamerasCount > 1);\n this.hasTwoWayTalkdownInOperatorPortalPermissions =\n videoStreamingPermissions.hasTwoWayTalkdownInOperatorPortalPermissions;\n\n updateCameraGroupAndCamera.call(this, sortedCameraGroups, cameras);\n\n this.onvifPtzPresetManager.setPresets(onvifPtzPresets);\n\n setInitialSetupDone.call(this);\n }\n\n /**\n * Performs the necessary actions when a live video player begins streaming.\n *\n * Note that this may get called without onPlayEnded executing first.\n * (e.g. if a player is actively streaming and a user switches the stream quality,\n * causing the video source to reinitialize without explicitly disconnecting first).\n */\n @action\n onPlayStarted(globalDeviceId: string): void {\n setCameraIsPlayingProperty(this.activeCameras, true, globalDeviceId);\n }\n\n /**\n * Performs the necessary actions when a live video player stops streaming.\n *\n * This should only occur when the player transitions from a playing state to a not-playing state.\n */\n @action\n onPlayEnded(globalDeviceId: string): void {\n setCameraIsPlayingProperty(this.activeCameras, false, globalDeviceId);\n }\n\n /**\n * When a device on live video times out, lets set the moreThanOneCameraTimedOut property\n */\n @action\n onTimeout(globalDeviceId: string): void {\n setCameraProperties(\n this.activeCameras,\n {\n hasStreamTimedOut: true\n },\n globalDeviceId\n );\n\n const { cameraItems } = this;\n\n const timedOutCameras = cameraItems.filter((cameraItem) => cameraItem.model?.hasStreamTimedOut);\n\n set(this, 'moreThanOneCameraTimedOut', timedOutCameras.length > 1);\n }\n\n /**\n * Helper method to enable calling actions in the super class.\n */\n @action\n sendAction(name: string, ...args: any) {\n this.actions[name].call(this, ...args);\n }\n}\n\ndeclare module '@glint/environment-ember-loose/registry' {\n export default interface Registry {\n 'Video::LiveVideo': typeof LiveVideo;\n }\n}\n","import { precompileTemplate } from \"@ember/template-compilation\";\nexport default precompileTemplate(\"\\n
\\n \\n
\\n\",{ moduleName: \"customer-site/components/video/video-player/overlay/live-overlay/index.hbs\" })","/* import __COLOCATED_TEMPLATE__ from './index.hbs'; */\nimport { computed, action, set } from '@ember/object';\nimport { or } from '@ember/object/computed';\nimport { later } from '@ember/runloop';\nimport { isPresent } from '@ember/utils';\nimport BaseVideoLiveOverlay from 'customer-site/components/video/video-player/overlay/base-live-overlay/index';\nimport { POST } from '@adc/ajax/services/adc-ajax';\nimport { intlPath } from '@adc/i18n/path';\nimport { downloadCrossOriginImage } from '@adc/ui-components/utils/download-file';\nimport { VideoPanTiltSettings } from '../../../../../enums/CustomerPageUrl';\nimport { panTilt, zoom } from '../../../../../utils/video/general';\nimport {\n ButtonMoreOptions,\n ButtonPanTilt,\n ButtonSettings,\n ButtonRequestRecordingAndSnapshot,\n ButtonDetailedOsd,\n ButtonDeterrent,\n ButtonOperatorLastViewed,\n ButtonOperatorAudioNotAvailable,\n ButtonAssociatedDeviceActions,\n ButtonLight\n} from '../../overlay/player-buttons/index';\n\nimport type { BaseVideoLiveOverlayArgs } from 'customer-site/components/video/video-player/overlay/base-live-overlay/index';\nimport type { RelativeDirection } from 'customer-site/enums/RelativeDirection';\nimport type CameraLight from 'customer-site/models/devices/camera-light';\nimport type Camera from 'customer-site/models/video/devices/camera';\nimport type Snapshot from 'customer-site/models/video/snapshot';\nimport type { OperatorAudioNotAvailableButtonContents, PtzPosition } from '../general-overlay-features';\n\n// The number of milliseconds to show the failure svg icon on the button before hiding the overlay.\nconst FailureIconTimeoutMilliseconds = 2000;\n// The number of milliseconds to wait before allowing another requestRecording call for onvif cameras.\nconst OnvifCheckRecencyMilliseconds = 60000;\n\ninterface VideoLiveOverlayArgs extends BaseVideoLiveOverlayArgs {\n associatedDevicesAction: () => void;\n cameraLight: CameraLight;\n cameraSpeakerAlreadyInUse: boolean;\n cannotDoBrowserUploadsForOperatorSite: boolean;\n canViewSettings: boolean;\n connectUsersMicrophoneAudio: () => Promise;\n currentPreset: 'Full' | 'Center';\n didOperatorViewWithinADay: boolean;\n didTwoWayAudioConnectionRefresh: boolean;\n displayAssociatedDevicesActionsPopover: boolean;\n displayOperatorAudioNotAvailablePopover: boolean;\n disableTwoWayAudio: boolean;\n displayPanTiltPopover: boolean;\n displayCameraButtonsPopover: boolean;\n enableCameraAudioAfterPauseStarted: () => void;\n forceHideIdleAudioIcon: boolean;\n forceShowOverlayForOperatorLastViewed: boolean;\n forceShowOverlayForMicrophone: boolean;\n forceShowWarningSoundForHelpTour: boolean;\n forceShowOverlayForVolumeSlider: boolean;\n hasAutoplayFailed: boolean;\n hasBlockedMicrophoneAccess: boolean;\n hasLiveViewBuzzDoorAccess: boolean;\n isAudioFullDuplex: boolean;\n isEndToEndStreamUsingTurn: boolean;\n isMicrophoneConnected: boolean;\n isWarningSoundOn: boolean;\n operatorAudioNotAvailableButtonContents?: OperatorAudioNotAvailableButtonContents;\n physicalPtzPosition: PtzPosition | null;\n refreshModel: () => void;\n selectPreset: (presetId: string) => Promise;\n shouldShowMicrophoneConnectionSpinner: boolean;\n toggleMuteMicrophone: () => void;\n toggleWarningSound(areButtonsInPopover: boolean): boolean | Promise;\n toggleOperatorLastViewedPopover(areButtonsInPopover: boolean): void;\n updatePtzPosition: (position: PtzPosition) => void;\n}\n\n/**\n * @classdesc\n * The overlay for live-view that fits on top of the player and displays information about the current streaming status.\n */\n@intlPath({ path: 'video/video-player/overlay/live-overlay' })\nexport default class VideoLiveOverlay<\n T extends VideoLiveOverlayArgs = VideoLiveOverlayArgs\n> extends BaseVideoLiveOverlay {\n /**\n * The current hybrid swap icon class to show, or null if we should not display the hybrid swap icon.\n *\n */\n hybridSwapIconToShow?: string;\n\n /**\n * Is the player currently expanded?\n *\n */\n isPlayerExpanded = false;\n\n /**\n * Which buttons to enable on the overlay\n */\n @computed(\n 'args.{operatorAudioNotAvailableButtonContents.displayButton,camera,canViewSettings,didOperatorViewWithinADay,hasLiveViewBuzzDoorAccess,isOperatorSite,isOeStream}',\n 'hasDetailedOsdOption'\n )\n get enabledButtons(): Array {\n const {\n canViewSettings,\n isOperatorSite,\n didOperatorViewWithinADay,\n operatorAudioNotAvailableButtonContents,\n hasLiveViewBuzzDoorAccess,\n camera,\n isOeStream\n } = this.args,\n { hasDetailedOsdOption } = this;\n\n const buttons = [ButtonMoreOptions];\n\n if (!camera.inCriticalDataMode) {\n buttons.push(ButtonPanTilt, ButtonDeterrent, ButtonLight);\n\n // If the user has stream stats permission (internal beta) and is streaming through OESP\n if (isOeStream && hasDetailedOsdOption) {\n buttons.push(ButtonDetailedOsd);\n }\n }\n\n if (!isOperatorSite) {\n if (!camera.inCriticalDataMode) {\n buttons.push(ButtonRequestRecordingAndSnapshot);\n\n if (hasLiveViewBuzzDoorAccess && camera.hasAssociatedDevices) {\n buttons.push(ButtonAssociatedDeviceActions);\n }\n }\n\n if (didOperatorViewWithinADay) {\n buttons.push(ButtonOperatorLastViewed);\n }\n\n if (canViewSettings) {\n buttons.push(ButtonSettings);\n }\n } else {\n if (operatorAudioNotAvailableButtonContents?.displayButton) {\n buttons.push(ButtonOperatorAudioNotAvailable);\n }\n }\n\n return buttons;\n }\n\n /**\n * Are we currently hovering or clicking over the camera feed?\n *\n */\n isHoveringOrClicking = false;\n\n /**\n * Should the overlay be shown to display the requesting snapshot animation?\n *\n */\n forceShowOverlayForSnapshot = false;\n\n /**\n * Should the overlay be shown to display the requesting recording animation?\n *\n */\n forceShowOverlayForRecording = false;\n\n /**\n * Should the overlay be shown to display the microphone button?\n *\n */\n forceShowOverlayForMicrophone = false;\n\n /**\n * Should the overlay be shown to display the volume slider?\n *\n */\n forceShowOverlayForVolumeSlider = false;\n\n /**\n * Should the overlay be shown to display the operator last viewed button?\n *\n */\n forceShowOverlayForOperatorLastViewed = false;\n\n /**\n * Is the settings button visible? User needs sufficient permission in order to see this button\n * This is passed in from live-view-player\n *\n */\n canViewSettings = false;\n\n /**\n * The last time an API call was made to request a recording for an onvif camera.\n * This is used to prevent spamming of the request recording API.\n */\n lastOnvifRequestRecordingCallTime?: number;\n\n /**\n * Can the user manage presets?\n *\n * @function\n */\n @computed('contextManager')\n get canManagePresets(): boolean {\n // Do not copy this deprecated usage. If you see this, please fix it\n // eslint-disable-next-line @adc/ember/no-context-manager-get-route\n return isPresent(this.contextManager.getRouteItem(VideoPanTiltSettings));\n }\n\n /**\n * Should the bottom bar currently be showing in the overlay?\n *\n * @function\n */\n @computed('args.{camera.canPanTilt,isOperatorSite}')\n get showBottomBar(): boolean {\n return !this.args.isOperatorSite || this.args.camera.canPanTilt;\n }\n\n /**\n * Should the overlay be shown on the player?\n * Note: Separate properties are needed for requesting a snapshot and requesting a recording\n * in case a user clicks both on the same player, the overlay won't hide until the latest request's promise is fulfilled.\n *\n * @function\n */\n @or(\n 'args.{displayAssociatedDevicesActionPopover,displayOperatorAudioNotAvailablePopover,displayPanTiltPopover,displayCameraButtonsPopover,forceShowOverlayForMicrophone,forceShowOverlayForVolumeSlider,isSelectedForKeyboardPress,forceShowOverlayForOperatorLastViewed,forceShowOverlayForWarningSound,forceShowWarningSoundForHelpTour}',\n 'isHoveringOrClicking',\n 'forceShowOverlayForSnapshot',\n 'forceShowOverlayForRecording'\n )\n declare makeOverlayVisible: boolean;\n\n /**\n * Requests a recording from the camera, to be saved on the Saved Clips page.\n */\n @action requestRecording(buttonAnimation: Promise): Promise {\n const { camera } = this.args,\n { isOnvifCamera } = camera,\n { lastOnvifRequestRecordingCallTime } = this;\n\n // If we clicked this button from the bottom bar, show the bar until the api call completes.\n set(this, 'forceShowOverlayForRecording', !this.displayCameraButtonsPopover);\n\n // Set-up callback to run after button animation completes\n buttonAnimation.then(() => {\n // eslint-disable-next-line @adc/ember/no-is-destroyed\n if (!this.isDestroyed) {\n set(this, 'forceShowOverlayForRecording', false);\n }\n });\n\n // Check if less than 60 seconds have passed since the last API call for onvif cameras.\n if (\n isOnvifCamera &&\n lastOnvifRequestRecordingCallTime &&\n Date.now() - lastOnvifRequestRecordingCallTime < OnvifCheckRecencyMilliseconds\n ) {\n this.notificationManager.addError(this.intl.t('generic.video.videoRequestInProgress'));\n return Promise.reject();\n }\n\n const promise = this.ajax.apiRequest(\n `video/devices/cameras/requestRecording?id=${camera.id}`,\n undefined,\n null,\n POST\n );\n\n promise.then(() => {\n this.notificationManager.addSuccess(this.intl.t('generic.video.videoRequestSuccessful'));\n if (isOnvifCamera) {\n this.lastOnvifRequestRecordingCallTime = Date.now();\n }\n });\n\n promise.catch((error) => {\n this.notificationManager.addError(error.errors[0].detail);\n // Do not copy this deprecated usage. If you see this, please fix.\n // eslint-disable-next-line ember/no-runloop\n later(\n this,\n () => {\n // eslint-disable-next-line @adc/ember/no-is-destroyed\n if (!this.isDestroyed) {\n set(this, 'forceShowOverlayForRecording', false);\n }\n },\n FailureIconTimeoutMilliseconds\n );\n });\n\n return promise;\n }\n\n /**\n * Saves a current snapshot from the camera to the customer's computer.\n */\n @action saveSnapshot(buttonAnimation: Promise): Promise {\n // If we clicked this button from the bottom bar, show the bar until the api call completes.\n set(this, 'forceShowOverlayForSnapshot', !this.displayCameraButtonsPopover);\n\n // Set-up callback to run after button animation completes\n buttonAnimation.then(() => {\n // eslint-disable-next-line @adc/ember/no-is-destroyed\n if (!this.isDestroyed) {\n set(this, 'forceShowOverlayForSnapshot', false);\n }\n });\n\n // eslint-disable-next-line no-async-promise-executor\n return new Promise(async (resolve, reject) => {\n const fnThrowError = (error: any) => {\n this.notificationManager.addError(error);\n // Do not copy this deprecated usage. If you see this, please fix.\n // eslint-disable-next-line ember/no-runloop\n later(\n this,\n () => {\n // eslint-disable-next-line @adc/ember/no-is-destroyed\n if (!this.isDestroyed) {\n set(this, 'forceShowOverlayForSnapshot', false);\n }\n },\n FailureIconTimeoutMilliseconds\n );\n reject();\n };\n\n try {\n const snapshot: Snapshot = await (this.args.camera as Camera).belongsTo('snapshot').reload();\n\n if (!snapshot || snapshot.error) {\n fnThrowError(snapshot && snapshot.error);\n return;\n }\n\n const todayToString = this.intl.formatDateTz(new Date(), {\n format: 'shortDateTimeFormat'\n });\n\n await downloadCrossOriginImage(\n snapshot.url,\n this.intl.t('generic.video.savedSnapshotName', {\n cameraName: this.args.camera.description,\n // Replace colons : with unicode character U+A789, which can be saved in file names unlike standard colons.\n currentDate: todayToString.replace(/\\//g, '-').replace(/:/g, '꞉')\n })\n );\n\n resolve();\n } catch (ex) {\n fnThrowError(this.intl.t('generic.video.failedToGetSnapshot'));\n }\n });\n }\n\n /**\n * Handles the button animation for the warning sound button and delegates the result to toggleWarningSound.\n *\n * @param {boolean} areButtonsInPopover is the action being called from a button in a popover?\n * @param {Promise|undefined} buttonAnimation A promise that settles with a boolean based on the result/rejection from the button action.\n */\n @action onWarningSoundAction(areButtonsInPopover: boolean): boolean | Promise {\n // If we open the Warning Sound popover from the \"more options\" popover, close the \"more options\" popover.\n if (areButtonsInPopover && !this.args.isWarningSoundOn) {\n this.toggleMoreOptions();\n }\n\n return this.args.toggleWarningSound(areButtonsInPopover);\n }\n\n /**\n * Action for toggling lights from live view.\n */\n @action onLightAction(): void {\n const { camera } = this.args;\n this.ajax.apiRequest(`devices/cameraLights/${camera.id}/toggleLight`, undefined, null, POST);\n }\n\n /**\n * Action for toggling operator last viewed popover.\n */\n @action onOperatorLastViewedAction(areButtonsInPopover: boolean): void {\n if (areButtonsInPopover) {\n this.toggleMoreOptions();\n }\n\n this.args.toggleOperatorLastViewedPopover(areButtonsInPopover);\n }\n\n /**\n * Move the camera view up, down, left, or right.\n *\n * @param direction The direction in which we are moving.\n */\n @action panTilt(direction: RelativeDirection): void {\n panTilt(this.ajax, this.args.camera, direction);\n }\n\n /**\n * Zoom the camera in or out.\n *\n * @param direction The direction in which we are zooming.\n */\n @action zoom(direction: RelativeDirection): void {\n zoom(this.ajax, this.args.camera, direction);\n }\n}\n","import { precompileTemplate } from \"@ember/template-compilation\";\nexport default precompileTemplate(\"
\\n
\\n {{#if @isError}}\\n
\\n \\n
\\n {{/if}}\\n

{{this.popoverContent.message}}

\\n
\\n \\n
\\n\",{ moduleName: \"customer-site/components/video/video-player/overlay/warning-sound-popover/index.hbs\" })","/* import __COLOCATED_TEMPLATE__ from './index.hbs'; */\nimport Component from '@glimmer/component';\nimport { computed } from '@ember/object';\nimport { inject as service } from '@ember/service';\nimport { htmlSafe } from '@ember/template';\nimport { intlPath } from '@adc/i18n/path';\n\nimport './_style.scss';\nimport type ADCIntlService from '@adc/i18n/services/adc-intl';\nimport type { SafeString } from 'handlebars';\n\nexport interface WarningSoundPopoverArgs {\n activateWarningSound: () => Promise;\n isError: boolean;\n}\n\n/**\n * @classdesc\n *\n * Component that represents the confirmation popover for Warning Sound actions\n */\n@intlPath({ path: 'video/video-player/overlay/warning-sound-popover' })\nexport default class WarningSoundPopover extends Component {\n @service declare intl: ADCIntlService;\n\n /**\n * The internationalized content for the warning sound message and button.\n */\n @computed('args.isError')\n get popoverContent(): { button: string; message: SafeString } {\n let infoResourceKey = 'warningSoundActivationDescription',\n buttonResourceKey = 'turnOn';\n\n if (this.args.isError) {\n infoResourceKey = 'activateWarningSoundError';\n buttonResourceKey = 'tryAgain';\n }\n\n return {\n button: this.intl.t(`generic.${buttonResourceKey}`),\n message: htmlSafe(this.intl.t(`generic.video.warningSound.${infoResourceKey}`))\n };\n }\n}\n\ndeclare module '@glint/environment-ember-loose/registry' {\n export default interface Registry {\n 'Video::VideoPlayer::Overlay::WarningSoundPopover': typeof WarningSoundPopover;\n }\n}\n","import { precompileTemplate } from \"@ember/template-compilation\";\nexport default precompileTemplate(\"
\\n
\\n
\\n {{#if this.displayDeviceList}}\\n
\\n {{#each this.devicesWithStatus as |deviceWithStatus index|}}\\n \\n \\n
{{deviceWithStatus.device.description}}
\\n \\n \\n {{/each}}\\n
\\n {{else if this.displayActionList}}\\n
\\n
\\n {{this.selectedDevice.device.description}}\\n
\\n {{#each this.selectedDevice.actionList as |action index|}}\\n \\n
\\n \\n
\\n

{{action.text}}

\\n \\n {{/each}}\\n
\\n {{else}}\\n
\\n
\\n {{this.selectedDevice.device.description}}\\n
\\n {{#let (get this.selectedDevice.actionList 0) as |primaryAction|}}\\n \\n
\\n \\n
\\n

{{primaryAction.text}}

\\n \\n {{/let}}\\n {{#if this.displayMoreDevicesButton}}\\n \\n

{{tc this \\\"systemDevices\\\"}}

\\n \\n \\n {{/if}}\\n
\\n {{/if}}\\n
\\n
\\n
\",{ moduleName: \"customer-site/components/video/video-player/overlay/associated-devices-action-popover/index.hbs\" })","/* import __COLOCATED_TEMPLATE__ from './index.hbs'; */\nimport Component from '@glimmer/component';\nimport { tracked } from '@glimmer/tracking';\nimport { action, computed } from '@ember/object';\nimport { alias } from '@ember/object/computed';\nimport { inject as service } from '@ember/service';\nimport { task } from 'ember-concurrency';\nimport { POST } from '@adc/ajax/services/adc-ajax';\nimport { intlPath } from '@adc/i18n/path';\nimport { Unknown, Open, Closed, Buzz } from '../../../../../enums/CardReaderState';\nimport { Locked, Unlocked } from '../../../../../enums/LockStatus';\nimport { AccessControlDoor, Lock } from '../../../../../enums/ManagedDeviceType';\n\nimport './_style.scss';\nimport type ADCIntlService from '@adc/i18n/services/adc-intl';\nimport type BaseManagedDevice from 'customer-site/models/devices/base-managed-device';\nimport type Camera from 'customer-site/models/video/devices/camera';\nimport type AjaxService from 'customer-site/services/ajax';\n\nexport interface ActionButtonArgs {\n camera: Camera;\n}\n\ninterface DeviceStatusAttributes {\n icon: string;\n text: string;\n iconState: string;\n color?: string;\n desiredState?: number;\n}\n\nconst buzzingResource = 'components.video.video-player.overlay.associated-devices-action-popover.buzzingEllipsis';\nconst lockingResource = 'components.video.video-player.overlay.associated-devices-action-popover.lockingEllipsis';\nconst unlockingResource = 'components.video.video-player.overlay.associated-devices-action-popover.unlockingEllipsis';\n\n/**\n * @classdesc\n *\n * Component that represents the popover for the Associated Devices Action Popover.\n */\n@intlPath({ path: 'video/video-player/overlay/associated-devices-action-popover' })\nexport default class AssociatedDevicesActionPopover extends Component {\n @service declare ajax: AjaxService;\n @service declare intl: ADCIntlService;\n\n /**\n * List of devices that are associated with a given camera id.\n */\n @tracked\n associatedDevices: BaseManagedDevice[] = [];\n\n /**\n * The number of primary devices associated with the camera.\n */\n @alias('args.camera.primaryAssociatedDeviceIds.length')\n declare numPrimaryDevices: number;\n\n /**\n * Whether the list of associated devices should be displayed.\n */\n @tracked displayDeviceList = false;\n\n /**\n * Whether the possible actions of an associated device should be displayed.\n */\n @tracked displayActionList = false;\n\n /**\n * Keeps track of the index in associatedDevices of the device selected in the associated devices list.\n */\n @tracked selectedDeviceIndex = 0;\n\n constructor(owner: unknown, args: ActionButtonArgs) {\n super(owner, args);\n this.loadAssociatedDevices.perform();\n }\n\n /**\n * Update the display to show all actions of a device that was selected from the Associated Devices list.\n * @param index\n */\n @action\n handleClickAssociatedDevice(index: number): void {\n this.selectedDeviceIndex = index;\n this.displayActionList = true;\n this.displayDeviceList = false;\n }\n\n /**\n * Fetches the associated devices from the backend to be shown in the popover.\n */\n loadAssociatedDevices = task({ drop: true }, async () => {\n this.associatedDevices = await this.args.camera.associatedDevices;\n this.updateDisplayDeviceList();\n this.updateDisplayActionList();\n });\n\n /**\n * Updates whether the device list should be displayed after associated devices is populated.\n */\n @action updateDisplayDeviceList() {\n this.displayDeviceList = this.numPrimaryDevices !== 1 && this.associatedDevices.length > 1;\n\n this.ajax.apiRequest(\n `api/settings/manageDevices/associatedDevices/reportPopoverFlowToWavefront/${this.displayDeviceList}`,\n undefined,\n null,\n POST\n );\n }\n\n /**\n * Updates whether the actions list should be displayed after associated devices is populated.\n */\n @computed('associatedDevices.length', 'numPrimaryDevices')\n get primaryDevice(): BaseManagedDevice | undefined {\n if (this.numPrimaryDevices === 0 && this.associatedDevices.length === 0) {\n return undefined;\n }\n return this.associatedDevices[0];\n }\n\n @action updateDisplayActionList() {\n this.displayActionList =\n this.associatedDevices.length === 1 && (this.numPrimaryDevices === 0 || this.numPrimaryDevices === 1);\n if (this.displayActionList) {\n this.displayDeviceList = false;\n }\n }\n\n /**\n * Returns if a device is the Primary Device and being displayed in the popover as the Primary Device.\n */\n isDisplayedPrimaryDevice(device: BaseManagedDevice): boolean {\n return device === this.associatedDevices[0] && this.numPrimaryDevices === 1 && !this.displayActionList;\n }\n\n /**\n * Returns the selected device (from the associated devices list) with status and actions.\n * If selectedDeviceIndex is default value (0), the primary device is returned.\n */\n get selectedDevice(): {\n device: BaseManagedDevice | null;\n deviceStatus: DeviceStatusAttributes;\n actionList: DeviceStatusAttributes[];\n } {\n return this.devicesWithStatus[this.selectedDeviceIndex];\n }\n\n /**\n * Whether the More Devices button should be displayed at the bottom of the popover.\n */\n get displayMoreDevicesButton(): boolean {\n return this.associatedDevices.length > 1;\n }\n\n /**\n * Whether the action button should be disabled.\n * Should be disabled for devices in an Unknown state.\n * In the primary action view for Access Control devices, the only action should be Buzz Open and disabled when the device is in an Open state.\n */\n get isActionDisabled(): boolean {\n if (this.selectedDevice && this.selectedDevice.device) {\n return this.selectedDevice.device.getState().state === Unknown;\n }\n\n return false;\n }\n\n /**\n * Creates an array of objects containing the device status for each associated device.\n */\n get deviceStatusArray(): DeviceStatusAttributes[] {\n return this.associatedDevices.map((device) => this.deviceStatus(device));\n }\n\n /**\n * Creates an array of device action arrays, mapped to each corresponding associated device.\n */\n get deviceActionList(): DeviceStatusAttributes[][] {\n return this.associatedDevices.map((device) => this.deviceActionStatus(device));\n }\n\n /**\n * Maps each associated device to its corresponding device status.\n */\n get devicesWithStatus(): {\n device: BaseManagedDevice | null;\n deviceStatus: DeviceStatusAttributes;\n actionList: DeviceStatusAttributes[];\n }[] {\n return this.deviceStatusArray.map((deviceStatus, index) => {\n const device = this.associatedDevices[index],\n actionList = this.deviceActionList[index];\n return { device, deviceStatus, actionList };\n });\n }\n\n /**\n * Executes the action on the device clicked/selected, changing its state.\n *\n * @param {number} selectedActionIndex the index in actionList of the action, keeps track of which action to execute.\n */\n @action\n changeSelectedDeviceState(selectedActionIndex: number): void {\n // No action if no device\n if (!this.selectedDevice.device) {\n return;\n }\n\n const deviceType = this.selectedDevice.device.managedDeviceType;\n const stateInfo = this.selectedDevice.device.getState();\n const { inTransition, state } = stateInfo;\n\n // Block action while device is transitioning status\n if (inTransition || state === Unknown) {\n return;\n }\n\n switch (deviceType) {\n case AccessControlDoor: {\n const newState =\n {\n [Closed]: this.selectedDevice.actionList[selectedActionIndex].desiredState,\n [Open]: Closed\n }[state] || state;\n\n this.selectedDevice.device.executeStateChange(newState, false);\n break;\n }\n case Lock: {\n const newState =\n {\n [Locked]: Unlocked,\n [Unlocked]: Locked\n }[state] || state;\n\n this.selectedDevice.device.executeStateChange(newState, false);\n break;\n }\n }\n }\n\n /**\n * Provides the icon, text, state device for the popover.\n */\n deviceStatus(device: BaseManagedDevice): DeviceStatusAttributes {\n // Ensure associated devices list is populated.\n if (device) {\n const deviceType = device.managedDeviceType;\n const stateInfo = device.getState();\n const { inTransition, state } = stateInfo;\n\n switch (deviceType) {\n case AccessControlDoor: {\n const stateText =\n {\n [Open]: inTransition ? unlockingResource : 'generic.unlocked',\n [Closed]: inTransition ? lockingResource : 'generic.locked',\n [Buzz]: inTransition ? buzzingResource : 'generic.buzzOpen'\n }[state] || 'generic.unknown';\n\n const stateString =\n {\n [Open]: 'open-hd',\n [Closed]: 'closed-hd',\n [Buzz]: 'buzz-hd'\n }[state] || 'unknown';\n\n return {\n icon: 'access-control-access-point-device',\n text: this.intl.t(stateText),\n iconState: stateString\n };\n }\n case Lock: {\n const stateText =\n {\n [Locked]: inTransition ? lockingResource : 'generic.locked',\n [Unlocked]: inTransition ? unlockingResource : 'generic.unlocked'\n }[state] || 'generic.unknown';\n\n const stateString =\n {\n [Locked]: 'locked',\n [Unlocked]: 'unlocked'\n }[state] || 'unknown';\n\n return {\n icon: 'lock',\n text: this.intl.t(stateText),\n iconState: stateString\n };\n }\n }\n }\n // Error case.\n return {\n icon: 'access-control-access-point-device',\n text: this.intl.tc(this, 'deviceLoadingError'),\n iconState: 'unknown'\n };\n }\n\n /**\n * Returns an array of all possible device actions (status opposite of current state) based on the given device's type and state.\n */\n deviceActionStatus(device: BaseManagedDevice): DeviceStatusAttributes[] {\n if (!device) {\n return [];\n }\n\n const deviceType = device.managedDeviceType;\n const { inTransition, state } = device.getState();\n const actionList: DeviceStatusAttributes[] = [];\n\n switch (deviceType) {\n case AccessControlDoor: {\n if (state === Closed) {\n // Buzz\n actionList.push({\n icon: 'access-control-access-point-device',\n text: this.intl.t(inTransition ? lockingResource : 'generic.buzzOpen'),\n iconState: inTransition ? 'closed-hd' : 'buzz-hd',\n color: inTransition ? 'red' : 'green',\n desiredState: Buzz\n });\n if (!inTransition) {\n // Unlock\n actionList.push({\n icon: 'access-control-access-point-device',\n text: this.intl.t(inTransition ? lockingResource : 'generic.unlock'),\n iconState: inTransition ? 'closed-hd' : 'open-hd',\n color: inTransition ? 'red' : 'green',\n desiredState: Open\n });\n }\n } else if (state === Open) {\n // Lock\n actionList.push({\n icon: 'access-control-access-point-device',\n text: this.intl.t(inTransition ? unlockingResource : 'generic.lock'),\n iconState: inTransition ? 'open-hd' : 'closed-hd',\n color: inTransition ? 'green' : 'red',\n desiredState: Closed\n });\n } else if (state === Buzz) {\n // Buzzing\n actionList.push({\n icon: 'access-control-access-point-device',\n text: this.intl.tc(this, 'buzzingEllipsis'),\n iconState: 'buzz-hd',\n color: 'green',\n desiredState: Buzz\n });\n if (!inTransition) {\n // Unlock\n actionList.push({\n icon: 'access-control-access-point-device',\n text: this.intl.t('generic.unlock'),\n iconState: 'open-hd',\n color: 'green',\n desiredState: Open\n });\n }\n } else {\n // Buzz Error\n actionList.push({\n icon: 'access-control-access-point-device',\n text: this.intl.t('generic.buzzOpen'),\n iconState: 'buzz-hd',\n color: 'green',\n desiredState: Buzz\n });\n if (!inTransition) {\n // Unlock Error\n actionList.push({\n icon: 'access-control-access-point-device',\n text: this.intl.t('generic.unlock'),\n iconState: 'open-hd',\n color: 'green',\n desiredState: Open\n });\n }\n }\n break;\n }\n case Lock: {\n if (state === Locked) {\n // Unlock\n actionList.push({\n icon: 'lock',\n text: this.intl.t(inTransition ? lockingResource : 'generic.unlock'),\n iconState: inTransition ? 'locked' : 'unlocked',\n color: inTransition ? 'red' : 'green',\n desiredState: Unlocked\n });\n } else if (state === Unlocked) {\n // Lock\n actionList.push({\n icon: 'lock',\n text: this.intl.t(inTransition ? unlockingResource : 'generic.lock'),\n iconState: inTransition ? 'unlocked' : 'locked',\n color: inTransition ? 'green' : 'red',\n desiredState: Locked\n });\n } else {\n // Lock Error\n actionList.push({\n icon: 'lock',\n text: this.intl.t('generic.unlock'),\n iconState: 'unlocked',\n color: 'green',\n desiredState: Unlocked\n });\n }\n break;\n }\n }\n return actionList;\n }\n}\n\ndeclare module '@glint/environment-ember-loose/registry' {\n export default interface Registry {\n 'Video::VideoPlayer::Overlay::AssociatedDevicesActionPopover': typeof AssociatedDevicesActionPopover;\n }\n}\n","import { precompileTemplate } from \"@ember/template-compilation\";\nexport default precompileTemplate(\"\\n
\\n {{#if (or @camera.osdOverlayEnabled this.hasDetailedOsdEnabled)}}\\n \\n {{else if @isOperatorSite}}\\n
\\n
\\n

{{@camera.description}}

\\n
\\n
\\n {{/if}}\\n\\n \\n \\n \\n \\n \\n \\n

{{this.operatorLastViewedPopoverText}}

\\n \\n \\n

{{this.operatorAudioNotAvailableButtonContents.buttonText}}

\\n {{#if this.operatorAudioNotAvailableButtonContents.streamRetryable}}\\n \\n {{/if}}\\n \\n \\n \\n \\n \\n {{#if this.isWarningSoundOn}}\\n \\n {{else if (or @isSelectedForKeyboardPress @isDraggingOver)}}\\n \\n {{/if}}\\n
\\n
\",{ moduleName: \"customer-site/components/video/video-player/live-view-player/index.hbs\" })","/* import __COLOCATED_TEMPLATE__ from './index.hbs'; */\nimport { tracked } from '@glimmer/tracking';\nimport { next } from '@adc/ember-utils/utils/runloop';\nimport { computed, action, setProperties, set } from '@ember/object';\nimport { alias, or, and, not } from '@ember/object/computed';\nimport { inject as service } from '@ember/service';\nimport { htmlSafe } from '@ember/template';\nimport { task, timeout } from 'ember-concurrency';\nimport BaseLivePlayer from 'customer-site/components/video/video-player/base-live-player/index';\nimport { MICROPHONE_ACCESS_COOKIE_NAME } from 'customer-site/components/video/video-player/base-video-player';\nimport {\n CENTER_PRESET_ZOOM_AMOUNT,\n CENTER_PTZ_PRESET\n} from 'customer-site/components/video/video-player/overlay/base-overlay';\nimport { DefaultHalfDuplexReenableAudioTimeoutMs } from 'customer-site/components/video/video-player/overlay/two-way-audio-buttons/index';\nimport { Invalid } from 'customer-site/enums/CameraSirenStatus';\nimport {\n None,\n HasSpeaker,\n HasMicrophone,\n HasSpeakerAndMic\n} from 'customer-site/enums/OnvifCameraAudioCapabilitiesEnum';\nimport { OperatorAudioNotAvailableButtonRefreshedStream } from 'customer-site/enums/TrackedEvent';\nimport {\n NUM_MILLISECONDS_IN_DAY,\n NUM_MILLISECONDS_IN_HOUR,\n NUM_MILLISECONDS_IN_MINUTE\n} from 'customer-site/utils/datetime';\nimport { intlPath } from '@adc/i18n/path';\nimport { getModalFooterButton } from '@adc/ui-components/components/modals/base/footer/modal-footer';\nimport { getPlayerId } from '@adc/video-player/components/base-player';\nimport { BaseVideoIdPrefix } from '@adc/video-player/components/live-video-player';\nimport { AudioRecordingState } from '@oecommon/oscar-js';\nimport addDays from 'date-fns/addDays';\nimport differenceInMilliseconds from 'date-fns/differenceInMilliseconds';\nimport { VideoCameraSettingsOverview, VideoMainSettings } from '../../../../enums/CustomerPageUrl';\nimport { StreamUsage } from '../../../../enums/StreamUsage';\nimport { goToPreset, transitionToSettings } from '../../../../utils/video/general';\n\nimport './_style.scss';\n\nconst MoreOptionsButtonClass = '.more-options-button',\n WarningSoundButtonClass = '.warning-sound-button',\n AssociatedDevicesActionButtonClass = '.associated-devices-actions-button',\n OperatorLastViewedButtonClass = '.operator-last-viewed-button',\n OperatorAudioNotAvailableButtonClass = '.operator-audio-not-available-button',\n OperatorAudioRetryNotificationDisplayTimeMs = 10000,\n OespTwoWayAudioTimeoutMs = DefaultHalfDuplexReenableAudioTimeoutMs;\n\n/**\n * Gets a popover Id with a specific button class, using the unique ID for this player.\n */\nfunction getPopoverId(buttonClass) {\n return `#${this.playerIdHtml} ${buttonClass}`;\n}\n\n/**\n * Handle a camera Warning Sound start request and manage the dialog modal upon completion.\n *\n * @returns {Promise}\n */\nasync function requestWarningSound() {\n const { camera, warningSound } = this,\n cameraSiren = await camera.cameraSiren,\n warningSoundPromise = new Promise((resolve) => {\n this.warningSoundResolver = resolve;\n });\n\n await warningSound.start(cameraSiren);\n const result = await warningSoundPromise;\n\n if (!result) {\n throw Error();\n }\n}\n\n/**\n * Handle a camera warning sound stop request and update the UI upon completion.\n *\n * @param { boolean } isForTwoWayAudio Is the Warning Sound being stopped to start two-way audio?\n * @returns {Promise}\n */\nasync function requestStopWarningSound(isForTwoWayAudio) {\n const { camera, warningSound } = this,\n cameraSiren = await camera.cameraSiren;\n\n await warningSound.stop(cameraSiren, isForTwoWayAudio);\n}\n\n/**\n * Spawn a simple dialog to show that a Warning Sound is disabled on a camera.\n */\nfunction showWarningSoundDisabledDialog() {\n const { canViewSettings, contextManager, intl, modals } = this,\n buttons = [];\n\n // If the user has the ability to change settings, display a button to go to the settings page.\n if (canViewSettings) {\n buttons.push(getModalFooterButton(intl.t('generic.settings'), () => goToSettings.call(this), 'btn-primary'));\n }\n\n const infoText = contextManager.identityModel.isOperatorSite\n ? htmlSafe(intl.t('generic.video.warningSound.warningSoundDisabledInfoOperatorSite'))\n : htmlSafe(intl.t('generic.video.warningSound.warningSoundDisabledInfo'));\n modals.showInfoModal({\n title: intl.t('generic.video.warningSound.warningSoundDisabledHeader'),\n svg: 'alarm',\n info: infoText,\n css: 'live-video-player-info-dialog',\n buttons\n });\n}\n\n/**\n * Navigate to the settings route if possible.\n */\nfunction goToSettings() {\n const { contextManager, store, camera, canViewSettings } = this;\n transitionToSettings(contextManager, store, camera, VideoMainSettings, canViewSettings);\n}\n\n/**\n * @classdesc\n * Component for displaying a video player for live view.\n */\n@intlPath({ path: 'video.video-player.live-view-player' })\nexport default class LiveViewPlayer extends BaseLivePlayer {\n /** @override */\n playerType = StreamUsage.LiveView;\n\n @service notificationManager;\n @service store;\n @service('video.warning-sound') warningSound;\n @service('video.video-preloader') videoPreloader;\n\n /**\n * If there 2 or more cameras on the page that are in a timed out state. Set by the parent component\n *\n * @type {boolean}\n */\n moreThanOneCameraTimedOut = false;\n\n // region Overlay and Sizing\n\n /**\n * Should the overlay be forced visible to show the Warning Sound button during help tour?\n *\n * @type {boolean}\n */\n @tracked forceShowOverlayForWarningSound = false;\n\n /**\n * Whether settings button is visible or not\n * @type {boolean}\n */\n @computed('isEnterprise', 'contextManager')\n get canViewSettings() {\n // Do not copy this deprecated usage. If you see this, please fix it\n // eslint-disable-next-line @adc/ember/no-context-manager-get-route\n return this.isEnterprise || this.contextManager.getRouteItem(VideoCameraSettingsOverview) !== undefined;\n }\n\n get videoPreloaderDetail() {\n if (this.currentStreamIsEndToEnd) {\n return this.videoPreloader.getVideoPreloaderDetail(getPlayerId(BaseVideoIdPrefix, this.camera.id));\n }\n\n return undefined;\n }\n\n // endregion\n\n // region Pan Tilt Zoom\n\n /**\n * The current preset for the PTZ camera.\n *\n * @type {string|null}\n */\n @tracked currentPreset;\n\n /**\n * Should we display the pan tilt preset popover?\n *\n * @type {boolean}\n */\n @tracked displayPanTiltPopover = false;\n\n /**\n * If this camera is a PTZ camera, have we gone to its default preset for the first time?\n * We store this value because we will only go to the default preset the first time the camera connects.\n *\n * @type {boolean}\n */\n @tracked hasGoneToPanTiltPreset = false;\n\n /**\n * If digital pan tilt zoom features are being enabled for this camera.\n *\n * @function\n * @returns {boolean}\n */\n @computed('camera.{canPanTilt,canZoom}')\n get enableDigitalZoomPanForCamera() {\n // If the camera can do both physical zooming and physical panning, we will disable all digital ptz features.\n return !(this.camera.canPanTilt && this.camera.canZoom);\n }\n\n /**\n * The current physical panTilt (x/y) and zoom positions for the selected device.\n *\n * @type {Object}\n */\n @tracked physicalPtzPosition = null;\n\n // endregion\n\n // region WebRTC End-to-End & OESP Two Way Audio\n\n /**\n * Is two-way audio active for this stream?\n * We must be actively using a stream that supports it, plus we need to pass any other needed permission or query param checks.\n *\n * @function\n * @returns {boolean}\n */\n @computed(\n 'camera.currentVideoSource.endToEndWebrtcConnectionInfo.supportsAudio',\n 'thirdPartyCameraAudioCapabilities',\n 'currentStreamIsEndToEnd',\n 'usesOesp',\n 'isProxyAndHasAudioSupport'\n )\n get isAudioActive() {\n // If we are viewing an OpenEye Player\n if (this.usesOesp) {\n return this.thirdPartyCameraAudioCapabilities !== None;\n }\n\n const isEndToEndAudioActive =\n this.camera.get('currentVideoSource.endToEndWebrtcConnectionInfo.supportsAudio') &&\n this.currentStreamIsEndToEnd;\n\n // get is needed since currentVideoSource is a proxy.\n return isEndToEndAudioActive || this.isProxyAndHasAudioSupport;\n }\n\n /**\n * Is two-way audio full duplex for this stream (as opposed to half duplex)?\n *\n * @type {boolean}\n */\n @or(\n 'camera.currentVideoSource.endToEndWebrtcConnectionInfo.supportsFullDuplex',\n 'camera.currentVideoSource.apexConnectionInfo.useFullDuplexAudio'\n )\n isAudioFullDuplex;\n\n /**\n * Deos the current stream use a proxy connection?\n *\n * @type {boolean}\n */\n @not('currentStreamIsEndToEnd')\n currentStreamIsProxy;\n\n /**\n * Is the current stream a proxy and does it support audio?\n *\n * @type {boolean}\n */\n @and('currentStreamIsProxy', 'proxyWebrtcConnectionInfo.supportsAudio')\n isProxyAndHasAudioSupport;\n\n /**\n * Wait for resolution of promise from async websocket for manual warning sounds.\n *\n * @type {function}\n */\n warningSoundResolver = undefined;\n\n /**\n * If this stream is an end-to-end stream with audio, have we connected with the user's microphone yet for sending audio?\n *\n * @type {boolean}\n */\n @or('{endToEndWebrtcConnectionInfo,proxyWebrtcConnectionInfo,apexConnectionInfo}.isMicrophoneConnected')\n isMicrophoneConnected;\n\n /**\n * Has our video player done a stream refresh after pressing the microphone button to enable?\n * This is relevant because the stream will start with different attributes after we press that microphone button in the overlay.\n *\n * @type {boolean}\n */\n @tracked didTwoWayAudioConnectionRefresh = false;\n\n /**\n * Should the overlay be shown to display the microphone button?\n *\n * @type {boolean}\n */\n @tracked forceShowOverlayForMicrophone = false;\n\n /**\n * Should the overlay be shown to display the microphone button?\n *\n * @type {boolean}\n */\n @tracked forceShowWarningSoundForHelpTour = false;\n\n /**\n * Should we disable two way audio? This is only used for OESP streams to temporarily to timeout the 2WA buttons when changing master panes.\n *\n * @type {boolean}\n */\n @tracked disableTwoWayAudio = false;\n\n /**\n * Did we just click the microphone button to enable talk down audio? True if toggleMicrophoneMute was hit, False if changeCameraAudio was hit.\n * This only applies to OESP streams.\n *\n * @type {boolean}\n */\n @tracked initiatedAudioRecordingStateChangeWithMicrophone = false;\n\n /**\n * Does the current video stream support getting audio from the camera?\n *\n * @returns boolean\n */\n @computed('isAudioActive', 'thirdPartyCameraAudioCapabilities', 'usesOesp')\n get supportsVolume() {\n return (\n this.isAudioActive &&\n (!this.usesOesp || [HasMicrophone, HasSpeakerAndMic].includes(this.thirdPartyCameraAudioCapabilities))\n );\n }\n\n /**\n * Does the current video stream support microphone talk-down audio to the camera?\n *\n * @returns boolean\n */\n @computed('isAudioActive', 'thirdPartyCameraAudioCapabilities', 'usesOesp')\n get supportsMicrophone() {\n return (\n this.isAudioActive &&\n (!this.usesOesp || [HasSpeaker, HasSpeakerAndMic].includes(this.thirdPartyCameraAudioCapabilities))\n );\n }\n\n /**\n * Should we show a spinner on the two-way-audio microphone button?\n * This is true if the audio recording state is connecting and the user clicked the microphone button because\n * we don't want the microphone spinner to appear unless the user interacts with the microphone.\n * This only applies to OESP streams.\n *\n * @returns boolean\n */\n @computed('playbackStateController.audioRecordingState', 'initiatedAudioRecordingStateChangeWithMicrophone')\n get shouldShowMicrophoneConnectionSpinner() {\n return (\n this.playbackStateController?.audioRecordingState === AudioRecordingState.Connecting &&\n this.initiatedAudioRecordingStateChangeWithMicrophone\n );\n }\n\n /**\n * The audio capabilities of a third party camera. This will be populated if we have a valid apexConnection\n * Corresponds to the enum values in OnvifCameraAudioCapabilitiesEnum.ts.\n *\n * @returns {number}\n */\n @alias('camera.currentVideoSource.apexConnectionInfo.audioCapabilities')\n thirdPartyCameraAudioCapabilities;\n\n // endregion\n\n // region Warning Sound\n\n /**\n * Is the warning sound active for this camera?\n *\n * @type {boolean}\n */\n @tracked isWarningSoundOn = false;\n\n /**\n * Can this player's camera play a Warning Sound?\n *\n * @returns {boolean}\n */\n @alias('camera.canSirenBeActivatedByLogin')\n canPlayWarningSound;\n\n /**\n * Was there an error starting the warning sound?\n *\n * @type {boolean}\n */\n @tracked warningSoundError = false;\n\n /**\n * Button element that the Warning Sound button popover should anchor to.\n * @type {string}\n */\n @tracked warningSoundButtonAnchorButton = '';\n\n /**\n * Used to keep track of whether or not the oespCamera is muted (assuming this in an oesp camera).\n * Only relevant in a live-view 2WA context.\n *\n * @type {boolean}\n */\n @tracked isOespCameraMuted = true;\n\n /**\n * Selector for this player's Warning Sound button.\n *\n * @returns {string}\n */\n @computed('playerIdHtml', 'warningSoundButtonAnchorButton')\n get warningSoundButtonSelector() {\n return getPopoverId.call(this, this.warningSoundButtonAnchorButton);\n }\n\n // endregion\n\n // Region Associated Devices Action Button\n\n /**\n * Should the Associated Devices Action popover be open?\n *\n * @type {boolean}\n */\n @tracked displayAssociatedDevicesActionPopover = false;\n\n /**\n * Button element that the Associated Devices Action Button button popover should anchor to.\n * @type {string}\n */\n @tracked associatedDevicesActionAnchorButton = AssociatedDevicesActionButtonClass;\n\n /**\n * Selector for this player's Associated Devices Action Button button.\n *\n * @returns {string}\n */\n @computed('playerIdHtml', 'associatedDevicesActionAnchorButton')\n get associatedDevicesActionSelector() {\n return getPopoverId.call(this, this.associatedDevicesActionAnchorButton);\n }\n\n //endregion\n\n // region Operator Last Viewed\n\n /**\n * Should the overlay be shown to display the Operator Last Viewed button?\n *\n * @type {boolean}\n */\n @tracked forceShowOverlayForOperatorLastViewed = false;\n\n /**\n * Button element that the Operator Last Viewed button popover should anchor to.\n * @type {string}\n */\n @tracked operatorLastViewedAnchorButton = '';\n\n /**\n * Selector for this player's Operator Last Viewed button.\n *\n * @returns {string}\n */\n @computed('playerIdHtml', 'operatorLastViewedAnchorButton')\n get operatorLastViewedButtonSelector() {\n return getPopoverId.call(this, this.operatorLastViewedAnchorButton);\n }\n\n /**\n * The calculated time difference in milliseconds between current time and the time an operator last viewed the camera's live view.\n * Returns null if the camera has not been viewed by an operator.\n *\n * @returns {number|null}\n */\n @computed('camera.lastOperatorViewedTime')\n get operatorLastViewedTimeDifferenceMS() {\n const now = new Date(),\n lastOperatorViewedTime = this.camera.lastOperatorViewedTime;\n if (lastOperatorViewedTime == null) {\n return null;\n }\n\n return Math.abs(\n now.getTime() -\n lastOperatorViewedTime.getTime() +\n lastOperatorViewedTime.getTimezoneOffset() * NUM_MILLISECONDS_IN_MINUTE\n );\n }\n\n /**\n * Has the camera been viewed by an operator via VV or EE within the last day?\n *\n * @returns {boolean}\n */\n @computed('operatorLastViewedTimeDifferenceMS')\n get didOperatorViewWithinADay() {\n const timeDifference = this.operatorLastViewedTimeDifferenceMS;\n if (timeDifference == null) {\n return false;\n }\n return timeDifference < NUM_MILLISECONDS_IN_DAY;\n }\n\n /**\n * Text calculation for the Operator Last Viewed popover.\n *\n * @returns {string}\n */\n @computed('operatorLastViewedTimeDifferenceMS')\n get operatorLastViewedPopoverText() {\n const { intl, operatorLastViewedTimeDifferenceMS } = this;\n if (operatorLastViewedTimeDifferenceMS == null) {\n return '';\n }\n // Get the hours difference between view time and current time as whole number rounded down.\n const hoursDifference = Math.floor(operatorLastViewedTimeDifferenceMS / NUM_MILLISECONDS_IN_HOUR);\n\n // Get the minutes difference after the hours difference is accounted for, e.g. 45 minutes from a total time of 6 hours and 45 minutes.\n const minutesModHoursDifference = Math.floor(\n (operatorLastViewedTimeDifferenceMS % NUM_MILLISECONDS_IN_HOUR) / NUM_MILLISECONDS_IN_MINUTE\n );\n\n // Handle 0 minutes case\n if (minutesModHoursDifference === 0) {\n switch (hoursDifference) {\n case 0:\n return intl.tc(this, 'operatorLastViewedLessThanMin');\n case 1:\n return intl.tc(this, 'operatorLastViewedSingleHour');\n default:\n return intl.tc(this, 'operatorLastViewedMultiHours', {\n hours: hoursDifference\n });\n }\n }\n\n return intl.tc(this, 'operatorLastViewedHoursAndMins', {\n hours: hoursDifference,\n minutes: minutesModHoursDifference\n });\n }\n\n // endregion\n\n // region Operator Audio Not Connecting Button\n\n /**\n * All properties related to the button shown in the operator portal\n * when audio is not available for the current stream.\n */\n @computed(\n 'currentStreamIsEndToEnd',\n 'cannotDoBrowserUploadsForOperatorSite',\n 'camera.currentVideoSource.endToEndWebrtcConnectionInfo.supportsAudio',\n 'isPlayingOrFrozen',\n 'hasTwoWayTalkdownInOperatorPortalPermissions',\n 'thirdPartyCameraAudioCapabilities',\n 'usesOesp'\n )\n get operatorAudioNotAvailableButtonContents() {\n const {\n currentStreamIsEndToEnd,\n isPlayingOrFrozen,\n clickOperatorAudioNotAvailable,\n intl,\n cannotDoBrowserUploadsForOperatorSite,\n hasTwoWayTalkdownInOperatorPortalPermissions,\n cameraRetriedInOperatorSite,\n thirdPartyCameraAudioCapabilities,\n usesOesp\n } = this;\n const cameraSupportsAudioOverProxy = this.camera.get(\n 'currentVideoSource.proxyWebrtcConnectionInfo.supportsAudio'\n ),\n cameraSupportsAudioOverEndToEnd = this.camera.get(\n 'currentVideoSource.endToEndWebrtcConnectionInfo.supportsAudio'\n ),\n cameraSupportsOespAudio = thirdPartyCameraAudioCapabilities !== None;\n\n const isUsingProxyAudio = cameraSupportsAudioOverProxy && !currentStreamIsEndToEnd,\n isUsingEndToEndAudio = cameraSupportsAudioOverEndToEnd && currentStreamIsEndToEnd,\n isUsingOespAudio = cameraSupportsOespAudio && usesOesp,\n cameraSupportsAudio =\n cameraSupportsAudioOverEndToEnd || cameraSupportsAudioOverProxy || cameraSupportsOespAudio,\n cameraIsntUsingAudio = !isUsingProxyAudio && !isUsingEndToEndAudio && !isUsingOespAudio,\n // If we are using an OESP stream and the camera either has a microphone OR speaker, but not both\n oespCameraSupportsSomeAudio =\n usesOesp && cameraSupportsOespAudio && thirdPartyCameraAudioCapabilities !== HasSpeakerAndMic,\n // The current stream isn't using audio (either wrong stream type or camera doesn't support audio) OR the camera only supports some audio features\n cameraIsntUsingTwoWayAudio = cameraIsntUsingAudio || oespCameraSupportsSomeAudio;\n\n let buttonText,\n streamRetryable = false,\n icon = 'mic-muted';\n\n if (cannotDoBrowserUploadsForOperatorSite) {\n buttonText = intl.t('components.video.live-video.clippyHealthCheckFailed');\n } else if (!cameraSupportsAudio) {\n buttonText = intl.tc(this, 'operatorMicrophoneNotAvailableForCamera');\n } else if (cameraRetriedInOperatorSite) {\n buttonText = intl.tc(this, 'operatorMicrophoneNotAvailableTryAgainRetry');\n streamRetryable = true;\n } else if (cameraSupportsAudio && cameraIsntUsingAudio) {\n buttonText = intl.tc(this, 'operatorMicrophoneNotAvailableTryAgain');\n streamRetryable = true;\n } else if (oespCameraSupportsSomeAudio) {\n // If this camera only has a speaker, note that we cannot use the volume slider.\n if (thirdPartyCameraAudioCapabilities === HasSpeaker) {\n icon = 'sound-off';\n buttonText = intl.tc(this, 'volumeSliderNotAvailableForCamera');\n }\n // If this camera only has a microphone, note that we cannot use the talk-down microphone button.\n else if (thirdPartyCameraAudioCapabilities === HasMicrophone) {\n buttonText = intl.tc(this, 'microphoneNotAvailableForCamera');\n }\n }\n\n return {\n buttonAction: clickOperatorAudioNotAvailable,\n buttonText,\n displayButton:\n // This button is only displayed for operator portals that use two-way talkdown\n hasTwoWayTalkdownInOperatorPortalPermissions &&\n // The current stream isn't using audio (either wrong stream type or camera doesn't support audio) OR the camera only supports some audio features\n cameraIsntUsingTwoWayAudio &&\n // We are in a \"playing\" state so we know the actual stream type\n isPlayingOrFrozen,\n streamRetryable,\n icon\n };\n }\n\n /**\n * Are we currently showing the operator's popover when a camera that supports audio isn't using audio?\n */\n @tracked\n displayOperatorAudioNotAvailablePopover = false;\n\n /**\n * The popover anchor for this player's Operator Last Viewed button.\n */\n @tracked\n operatorAudioNotAvailableButtonSelector = getPopoverId.call(this, OperatorAudioNotAvailableButtonClass);\n\n /**\n * A boolean tracking if this camera retried itself in the operator site.\n * This may switch on if we retry because the camera didn't use end-to-end for audio access, and the operator clicked to retry the stream.\n */\n cameraRetriedInOperatorSite = false;\n\n // endregion\n\n // region BaseVideoPlayer Overrides\n\n /** @override */\n onPlayStarted() {\n super.onPlayStarted(...arguments);\n\n if (this.cameraRetriedInOperatorSite) {\n const cameraName = this.camera.description;\n if (this.currentStreamIsEndToEnd) {\n this.notificationManager.addSuccess(\n this.intl.tc(this, 'operatorMicrophoneRetrySucceeded', { cameraName }),\n OperatorAudioRetryNotificationDisplayTimeMs\n );\n } else {\n this.notificationManager.addWarning(\n this.intl.tc(this, 'operatorMicrophoneRetryFailed', { cameraName }),\n OperatorAudioRetryNotificationDisplayTimeMs\n );\n }\n }\n }\n\n /** @override */\n onPoorStartingConnection(/* playerId */) {\n // The stream has detected poor streaming conditions on stream start - pass message forward so page might lower stream resolution.\n this.onCameraHasPoorStartingConnection && this.onCameraHasPoorStartingConnection();\n }\n\n // endregion\n\n // region Tasks\n\n /**\n * Sets the warning sound state to active for the duration of the operation, then sets to inactive.\n *\n * @param { CameraSiren } warningSoundInfo The status info for the active warning sound\n *\n * @type {Task}\n */\n @task *updateWarningSoundDisplayTask(warningSoundInfo) {\n const end = warningSoundInfo.timestampEndUtc.getTime(),\n now = new Date().getTime();\n\n this.isWarningSoundOn = true;\n\n yield timeout(differenceInMilliseconds(end, now));\n\n this.isWarningSoundOn = false;\n }\n\n /**\n * Sets the oesp properties after initializing the videosource.\n *\n * @param {OespPlaybackStateController} controller The playback state controller used for OESP live view relays.\n *\n * @type {Task}\n */\n @task *setOespProperties(controller) {\n // This delays sending the playbackStateController to the openeye-player.\n // We want the player to be rendered before we attempt to connect the controller.\n yield next(() => {});\n\n setProperties(this, {\n hasStreamConnected: false,\n index: controller.playerCount++,\n playbackStateController: controller\n });\n }\n\n /**\n * When the selected master pane changes (video-streaming-features.selectedOespMasterPaneCameraId updates), this function will fire\n * and determine if we should temporarily disable two-way audio buttons for the given camera.\n *\n * @type {Task}\n */\n @task({ restartable: true }) *temporarilyDisableTwoWayAudioIfNeeded() {\n // If this camera is the selected master pane, don't disable the two-way audio buttons.\n if (!this.selectedOespMasterPaneCameraId || this.selectedOespMasterPaneCameraId === this.camera.id) {\n return;\n }\n\n // If this is an OESP stream, temporarily disable the two-way audio buttons.\n if (this.usesOesp) {\n this.disableTwoWayAudio = true;\n yield timeout(OespTwoWayAudioTimeoutMs);\n this.disableTwoWayAudio = false;\n }\n }\n\n // endregion\n\n // region Actions\n\n /**\n * This sends the parent of this controller a method that the parent can use for resuming the camera, if it is currently in a timed out state\n */\n @action sendParentResumeMethod() {\n if (!this.sendResumeMethod) {\n return;\n }\n\n this.sendResumeMethod(() => {\n if (this.hasStreamTimedOut) {\n this.retryConnection();\n }\n });\n }\n\n /**\n * Swaps the camera with the camera that is currently the largest one in hybrid view.\n */\n @action selectCameraWithLargeHybridCamera() {\n this.onSwapHybridLargeView();\n }\n\n /**\n * Moves the camera view to a specific preset.\n *\n * @param {string} presetId The preset ID as stored in the camera.\n */\n @action async selectPreset(presetId) {\n await goToPreset(this.ajax, this.camera, presetId);\n\n this.currentPreset = presetId;\n this.displayPanTiltPopover = false;\n this.physicalPtzPosition = {\n panTiltX: 0,\n panTiltY: 0,\n zoomLevel: presetId === CENTER_PTZ_PRESET ? CENTER_PRESET_ZOOM_AMOUNT : 0\n };\n }\n\n /**\n * Updates the panTilt or Zoom values for the device.\n *\n * @param {Object} ptzPosition contains either pantiltX/panTiltY number properties or zoomLevel number property (depending on if it was triggered by panTilt or zoom)\n * @param {Boolean} arePanTiltValues if pan and tilt values are being sent up (otherwise the zoom value is being sent up)\n */\n @action updatePtzPosition(ptzPosition, arePanTiltValues) {\n if (!ptzPosition) {\n return;\n }\n\n if (arePanTiltValues) {\n setProperties(this.physicalPtzPosition, {\n panTiltX: ptzPosition.panTiltX,\n panTiltY: ptzPosition.panTiltY\n });\n } else {\n set(this.physicalPtzPosition, 'zoomLevel', ptzPosition.zoomLevel);\n }\n\n const { zoomLevel, panTiltX, panTiltY } = this.physicalPtzPosition;\n\n if (!panTiltX && !panTiltY && zoomLevel === CENTER_PRESET_ZOOM_AMOUNT) {\n this.currentPreset = CENTER_PTZ_PRESET;\n } else {\n this.currentPreset = null;\n }\n }\n\n /**\n * Only relevant to OESP streams.\n * This function gets called when the svrIdRefreshedFromMicrophoneConnection value is updated.\n * Because all 3PC streams for a given SVR reload when the microphone is first connected,\n * this function ensures that the microphone talk-down is available for use for every reloaded camera on the SVR.\n */\n @action connectMicrophoneForAllCamerasOnSvr() {\n // If this is a 3PC stream and this camera is on the same SVR as the camera that refreshed the microphone connection.\n if (this.usesOesp && this.apexConnectionInfo.apexId === this.svrIdRefreshedFromMicrophoneConnection) {\n set(this, 'apexConnectionInfo.isMicrophoneConnected', true);\n this.didTwoWayAudioConnectionRefresh = true;\n }\n }\n\n /**\n * Handles a user clicking the microphone button to enable/disable microphone permissions.\n * If enabled, we reload the stream with the microphone enabled.\n * If disabled, we show the microphone access is blocked info modal.\n * This is for WebRTC end-to-end and OESP two-way audio streams.\n */\n @action connectUsersMicrophoneAudio() {\n const {\n isMicrophoneConnected,\n svrIdsWithMicrophoneConnectionInProgress,\n setMicrophoneConnectionInProgressForSvr,\n intl\n } = this;\n\n /**\n * If our SVR's ID is found in svrIdsWithMicrophoneConnectionInProgress, the SVR is already attempting to make a microphone connection.\n * To prevent OESP-specific errors caused by simultaneous attempts at microphone connection on the same SVR, we Promise.reject() in this case.\n */\n if (\n isMicrophoneConnected ||\n (this.usesOesp && svrIdsWithMicrophoneConnectionInProgress.has(this.apexConnectionInfo.apexId))\n ) {\n return Promise.reject();\n }\n\n setMicrophoneConnectionInProgressForSvr(this.usesOesp ? this.apexConnectionInfo.apexId : null, true);\n\n const audioPromise = navigator.mediaDevices.getUserMedia({ audio: true, video: false });\n\n audioPromise\n .then(async (stream) => {\n // Immediately stop the streaming tracks, otherwise the microphone usage icon still shows in tabs.\n stream.getTracks().forEach((track) => track.stop());\n\n this.didTwoWayAudioConnectionRefresh = true;\n this.shouldResetEndToEndStreamFailed = true;\n\n this.cookieManager.setEssentialCookie(MICROPHONE_ACCESS_COOKIE_NAME, '');\n\n if (this.usesOesp) {\n // Set the SVR ID in video-streaming-players so that all cameras on the SVR can use the microphone.\n this.setSvrIdRefreshedFromMicrophoneConnection(this.apexConnectionInfo.apexId);\n\n // Ensure that no audio is incoming from this SVR before we reload the players. Not doing so can result in audio persisting until browser refresh.\n if (this.oeAudioInfo && this.oeAudioInfo.svrIdWithAudio === this.apexConnectionInfo.apexId) {\n this.playbackStateController.changeCameraAudio(true, 0, false, this.index);\n this.setSelectedOespMasterPaneCameraId(this.camera.id);\n this.setOEAudioInfo(true, this.camera.id, this.apexConnectionInfo.apexId);\n }\n\n // Stop any audio recordings for the SVR.\n await this.playbackStateController.stopAudioRecording();\n }\n\n this.initializeVideoSource.perform();\n\n // (OESP only) remove this SVR from the list of SVRs with microphone connection in progress.\n setMicrophoneConnectionInProgressForSvr(this.usesOesp ? this.apexConnectionInfo.apexId : null, false);\n\n return Promise.resolve();\n })\n .catch(() => {\n // User denied permission so don't enable audio or restart the stream.\n if (!this.hasBlockedMicrophoneAccess) {\n this.modals.showInfoModal({\n title: intl.tc(this, 'microphoneIsBlocked'),\n svg: 'mic-muted',\n info: htmlSafe(`${intl.tc(this, 'microphoneIsBlockedText')}`),\n css: 'live-video-player-info-dialog'\n });\n this.hasBlockedMicrophoneAccess = true;\n this.cookieManager.setEssentialCookie(\n MICROPHONE_ACCESS_COOKIE_NAME,\n 'true',\n addDays(new Date(), 30)\n );\n }\n\n // (OESP only) remove this SVR from the list of SVRs with microphone connection in progress.\n setMicrophoneConnectionInProgressForSvr(this.usesOesp ? this.apexConnectionInfo.apexId : null, false);\n\n return Promise.reject();\n });\n\n return audioPromise;\n }\n\n /**\n * Handles a user clicking the button to mute the audio coming from the camera\n * and adjusting the volume slider to change the volume of the audio coming from the camera.\n * This is for WebRTC end-to-end two-way audio streams and OESP two-way audio streams\n *\n * @param {boolean} shouldMute Is the new state of camera audio muted?\n * @param {number} volume The new camera audio volume value.\n * @param {boolean} isEnabledAutomaticallyAfterDelay Is the camera audio being enabled automatically after a delay?\n * @param {boolean} cameraWasAutoMuted if the camera was automuted. We must automute cameras because SVRs only support audio from one camera at a time.\n * @param {boolean} oeSVRShouldMuteAudio If the SVR the camera is connected to should be muted.\n */\n @action changeCameraAudio(\n shouldMute,\n volume,\n isEnabledAutomaticallyAfterDelay = false,\n cameraWasAutoMuted = false,\n oeSVRShouldMuteAudio = false\n ) {\n const {\n currentStreamIsEndToEnd,\n webrtcStateController,\n playbackStateController,\n isProxyAndHasAudioSupport,\n camera,\n usesOesp,\n apexConnectionInfo,\n isAudioFullDuplex,\n supportsMicrophone,\n supportsVolume,\n isMicrophoneConnected,\n index\n } = this;\n\n // WebRTC\n if (currentStreamIsEndToEnd || isProxyAndHasAudioSupport) {\n webrtcStateController?.changeCameraAudio(shouldMute, volume, isEnabledAutomaticallyAfterDelay);\n }\n\n // OESP\n if (usesOesp) {\n this.isOespCameraMuted = shouldMute;\n // If this camera was auto-muted and it was on the same SVR, we can return because audio has been switched to the new pane\n if (cameraWasAutoMuted && !oeSVRShouldMuteAudio) {\n return;\n }\n\n // Since we used the volume button, we don't want to show the microphone connection spinner if the audio recording state is connecting.\n // We only want to show the spinner if the user interacts with the microphone button or this is a full-duplex context.\n this.initiatedAudioRecordingStateChangeWithMicrophone =\n isAudioFullDuplex && this.initiatedAudioRecordingStateChangeWithMicrophone;\n\n if (supportsVolume) {\n playbackStateController.changeCameraAudio(\n shouldMute,\n volume,\n isEnabledAutomaticallyAfterDelay,\n index,\n supportsMicrophone && isMicrophoneConnected\n );\n }\n\n // Only set the current OEAudioInfo if the camera was NOT auto-muted\n if (!cameraWasAutoMuted) {\n this.setSelectedOespMasterPaneCameraId(camera.id);\n this.setOEAudioInfo(shouldMute, camera.id, apexConnectionInfo.apexId);\n this.setForceHideIdleAudioIcon(false);\n }\n }\n }\n\n /**\n * Handles a user clicking the button to mute the user's microphone audio.\n * This is for WebRTC end-to-end two-way audio streams.\n *\n * @param {boolean} shouldMute Is the new state of microphone audio muted?\n * @param {boolean} cameraWasAutoMuted if the camera was automuted. We must automute cameras because SVRs only support audio from one camera at a time.\n * This can only be true in a full-duplex context.\n * @param {boolean} oeSVRShouldMuteAudio If the SVR the camera is connected to should be muted.\n * This can only be true in a full-duplex context.\n */\n @action toggleMuteMicrophone(shouldMute, cameraWasAutoMuted = false, oeSVRShouldMuteAudio = false) {\n const {\n webrtcStateController,\n playbackStateController,\n isAudioFullDuplex,\n oeAudioInfo,\n camera,\n usesOesp,\n apexConnectionInfo,\n isOespCameraMuted,\n index\n } = this;\n\n if (usesOesp) {\n // If this camera was auto-muted and it was on the same SVR, we can return because audio has been switched to the new pane.\n // This can only ever happen in a full-duplex context.\n if (cameraWasAutoMuted && !oeSVRShouldMuteAudio) {\n return;\n }\n\n // If a different camera is currently playing audio, we need to ensure that it is muted and the idle audio icon is not appearing when beginning talk down audio.\n // This is only relevant in a half-duplex context.\n if (!isAudioFullDuplex && oeAudioInfo && !shouldMute && camera.id !== oeAudioInfo.playerIdWithAudio) {\n // If the camera playing audio is on the same SVR.\n // Simply hide the idle audio icon. The audio will already be muted when talk down is started.\n if (apexConnectionInfo.apexId === oeAudioInfo.svrIdWithAudio) {\n this.setForceHideIdleAudioIcon(true);\n }\n\n // The camera playing audio is on a different SVR.\n // Set new OE Audio info to empty values to mute the previous camera and remove the idle audio icon.\n else {\n this.setOEAudioInfo(false, '', '');\n }\n }\n\n this.initiatedAudioRecordingStateChangeWithMicrophone = true;\n playbackStateController.toggleMicrophoneMute(shouldMute, index);\n\n if (!cameraWasAutoMuted) {\n this.setSelectedOespMasterPaneCameraId(camera.id);\n }\n\n // In a full duplex context, we need to set this camera as the one playing audio and hide the audio idle icon if the camera is muted.\n if (isAudioFullDuplex && !cameraWasAutoMuted) {\n this.setOEAudioInfo(false, camera.id, apexConnectionInfo.apexId);\n if (isOespCameraMuted) {\n this.setForceHideIdleAudioIcon(true);\n }\n }\n } else {\n webrtcStateController.toggleMicrophoneMute(shouldMute);\n }\n\n this.forceShowOverlayForMicrophone = !shouldMute && !this.isAudioFullDuplex;\n }\n\n /**\n * Toggle the camera's warning sound on or off.\n *\n * @param {boolean} areButtonsInPopover is this action being called from a button in a popover menu?\n */\n @action toggleWarningSound(areButtonsInPopover) {\n this.warningSoundButtonAnchorButton = areButtonsInPopover ? MoreOptionsButtonClass : WarningSoundButtonClass;\n\n if (this.isWarningSoundOn) {\n return this.stopWarningSound();\n }\n\n if (!this.camera.isWarningReactionEnabled) {\n showWarningSoundDisabledDialog.call(this);\n return false;\n }\n\n this.forceShowOverlayForWarningSound = true;\n return false;\n }\n\n /**\n * Request to start a Warning Sound on this player's camera.\n */\n @action activateWarningSound() {\n return requestWarningSound.call(this);\n }\n\n /**\n * Request that an active Warning Sound be stopped.\n *\n * @returns {Promise}\n */\n @action stopWarningSound() {\n return requestStopWarningSound.call(this, false);\n }\n\n /**\n * Cleanup the Warning Sound UI when the popover closes.\n */\n @action closeWarningSoundPopover() {\n this.forceShowOverlayForWarningSound = false;\n this.warningSoundError = false;\n this.warningSoundResolver = null;\n }\n\n /**\n * Displays the Associated Devices Actions popover and sets anchor\n */\n @action showAssociatedDevicesActions() {\n this.displayAssociatedDevicesActionPopover = true;\n }\n\n /**\n * Cleanup the Associated Devices Action UI when the popover closes.\n */\n @action closeAssociatedDevicesActionPopover() {\n this.displayAssociatedDevicesActionPopover = false;\n }\n\n /**\n * Toggle the Operator Last Viewed popover.\n *\n * @param {boolean} areButtonsInPopover is this action being called from a button in a popover menu?\n */\n @action toggleOperatorLastViewed(areButtonsInPopover) {\n this.operatorLastViewedAnchorButton = areButtonsInPopover\n ? MoreOptionsButtonClass\n : OperatorLastViewedButtonClass;\n\n this.forceShowOverlayForOperatorLastViewed = true;\n }\n\n /**\n * Action when an operator clicks the microphone button if a camera can support audio but isn't presently.\n *\n * @param {boolean} areButtonsInPopover Whether this action is being triggered from a camera action popover for small screens (true).\n */\n @action clickOperatorAudioNotAvailable(areButtonsInPopover) {\n let buttonClass = areButtonsInPopover ? MoreOptionsButtonClass : OperatorAudioNotAvailableButtonClass;\n this.operatorAudioNotAvailableButtonSelector = getPopoverId.call(this, buttonClass);\n this.displayOperatorAudioNotAvailablePopover = true;\n }\n\n /**\n * Restarts the stream in operator portal if camera supports audio but didn't use that streaming method.\n */\n @action restartStreamViaOperatorAudioNotAvailablePopover() {\n this.stats.logEvent(OperatorAudioNotAvailableButtonRefreshedStream);\n this.cameraRetriedInOperatorSite = true;\n this.retryEndToEndWithAudioRequest(false);\n this.displayOperatorAudioNotAvailablePopover = false;\n }\n\n /**\n * Cleanup the Operator Last Viewed UI when the popover closes.\n */\n @action closeOperatorLastViewedPopover() {\n this.forceShowOverlayForOperatorLastViewed = false;\n }\n\n /**\n * Handler for when the associated camera siren changes states.\n *\n * @returns {Promise}\n */\n @action async onSirenChange() {\n const cameraSiren = await this.camera.cameraSiren;\n\n if (!cameraSiren) {\n return;\n }\n\n if (cameraSiren.status === Invalid) {\n this.warningSoundError = true;\n this.warningSoundResolver?.(false);\n } else if (!this.isWarningSoundOn && cameraSiren.isActive) {\n // Don't re-update the display if we already know the sound is on\n this.closeWarningSoundPopover();\n this.updateWarningSoundDisplayTask.perform(cameraSiren);\n this.warningSoundResolver?.(true);\n } else if (this.isWarningSoundOn && !cameraSiren.isActive) {\n await this.updateWarningSoundDisplayTask.cancelAll();\n this.isWarningSoundOn = false;\n }\n }\n\n // endregion\n}\n","import { precompileTemplate } from \"@ember/template-compilation\";\nexport default precompileTemplate(\"
\\n
\\n {{@camera.description}}\\n
\\n {{#if @showLocation}}\\n {{@camera.system.description}}\\n {{/if}}\\n {{#if this.formattedOsdProperties.timeDisplay}}\\n
\\n
\\n
{{this.formattedOsdProperties.timeDisplay}}
\\n
\\n {{/if}}\\n
\\n
\\n\\n {{#if @hasDetailedOsdEnabled}}\\n
\\n {{this.formattedOsdProperties.resolutionDisplay}}\\n {{this.formattedOsdProperties.codecDisplay}}\\n {{this.formattedOsdProperties.bitRateDisplay}}\\n {{this.formattedOsdProperties.frameRateDisplay}}\\n
\\n {{/if}}\\n
\",{ moduleName: \"customer-site/components/video/video-player/oesp-osd/index.hbs\" })","/* import __COLOCATED_TEMPLATE__ from './index.hbs'; */\nimport Component from '@glimmer/component';\nimport { tracked } from '@glimmer/tracking';\nimport { action, computed } from '@ember/object';\nimport { once } from '@ember/runloop';\nimport { inject as service } from '@ember/service';\nimport { htmlSafe } from '@ember/template';\nimport { getPlayerSize } from 'customer-site/components/video/video-player/base-video-player';\nimport { formatResolution, formatVideoCodec, formatFrameRate, formatBitRate } from '@adc/video-player/utils/osd-utils';\nimport { utcToZonedTime } from 'date-fns-tz';\nimport format from 'date-fns/format';\nimport { getSizeStyleClassFromPlayerSize } from '../overlay/index';\n\nimport './_style.scss';\n\nconst DATE_FORMAT = 'yyyy-MM-dd';\nconst TIME_FORMAT = 'HH:mm:ss';\nconst DATETIME_FORMAT = `${DATE_FORMAT} ${TIME_FORMAT}`;\n\n/**\n * Sets the size style class of the OSD based off of the player dimensions.\n *\n * @returns\n */\nfunction setOsdSize() {\n const playerSize = getPlayerSize(this.args.playerDimensions, 0);\n\n if (playerSize == null) {\n return;\n }\n\n this.sizeStyleClass = `${getSizeStyleClassFromPlayerSize(playerSize)}-osd`;\n}\n\n/**\n * Formats an Instant (from @oecommon/plasma-js) to a string in the current timezone.\n *\n * @param {Instant} renderTime\n * @returns\n */\nfunction formatTime(renderTime) {\n const timeZone = this.intl.timeZone,\n date = renderTime.toDate();\n\n return format(utcToZonedTime(date, timeZone), DATETIME_FORMAT);\n}\n\n/**\n * @classdesc\n *\n * The on-screen display used for OESP streams.\n *\n * @class OespOsd\n */\nexport default class OespOsd extends Component {\n @service intl;\n\n /**\n * A class based off the player size.\n *\n * @type {string}\n */\n @tracked sizeStyleClass = '';\n\n /**\n * Getter for a htmlSafe wrapped size style class\n *\n * @type {SafeString}\n */\n get htmlSafeSizeStyleClass() {\n return htmlSafe(this.sizeStyleClass);\n }\n\n /**\n * Getter for the formatted video codec, which we try to cache since this shouldn't change mid-stream.\n *\n * @type {string}\n */\n get formattedVideoCodec() {\n const { streamStats } = this.args.osdProperties ?? {};\n\n // When we aren't given a video codec, assume the stream has ended and reset this value.\n if (!streamStats?.videoCodec) {\n // Do not copy this deprecated usage. If you see this, please fix it\n // eslint-disable-next-line ember/no-side-effects\n this.cachedFormattedVideoCodec = null;\n return null;\n }\n\n if (!this.cachedFormattedVideoCodec) {\n // Do not copy this deprecated usage. If you see this, please fix it\n // eslint-disable-next-line ember/no-side-effects\n this.cachedFormattedVideoCodec = formatVideoCodec(streamStats);\n }\n\n return this.cachedFormattedVideoCodec;\n }\n\n /**\n * An object holding all of the formatted OSD properties.\n *\n * @type {Object}\n */\n @computed('args.osdProperties', 'formattedVideoCodec')\n get formattedOsdProperties() {\n const { osdProperties } = this.args,\n { renderTime, streamStats } = osdProperties ?? {};\n\n return {\n timeDisplay: renderTime ? formatTime.call(this, renderTime) : null,\n resolutionDisplay: formatResolution(streamStats),\n codecDisplay: this.formattedVideoCodec,\n bitRateDisplay: formatBitRate(streamStats),\n frameRateDisplay: formatFrameRate(streamStats)\n };\n }\n\n /**\n * This schedules a single call to set the new OSD size.\n */\n @action updateOsdSize() {\n // Do not copy this deprecated usage. If you see this, please fix\n // eslint-disable-next-line ember/no-runloop\n once(this, setOsdSize);\n }\n}\n","import { action } from '@ember/object';\nimport { equal, or } from '@ember/object/computed';\nimport { inject as service } from '@ember/service';\nimport { task, timeout } from 'ember-concurrency';\nimport { DISCONNECTED_STATE } from 'customer-site/enums/VideoPlayerStateEnum';\nimport { NoError, NoPermissions, StreamNotAvailable } from 'customer-site/enums/VideoSourceError';\nimport { intlPath } from '@adc/i18n/path';\nimport BaseOverlay from '../base-overlay';\n\nimport type ADCIntlService from '@adc/i18n/services/adc-intl';\nimport type NotificationManager from '@adc/ui-components/services/notification-manager';\nimport type AjaxService from 'customer-site/services/ajax';\nimport type { BaseVideoOverlayArgs } from '../base-overlay';\n\n// The number of milliseconds to show the failure svg icon on the button before hiding the overlay.\nconst FailureLogTimeoutMilliseconds = 1000;\n\nexport interface BaseVideoLiveOverlayArgs extends BaseVideoOverlayArgs {\n playerState: number;\n isModifyingSettings: boolean;\n}\n\n/**\n * @classdesc\n * The overlay for field of view that fits on top of the player and displays information about the current streaming status.\n */\n@intlPath({ path: 'video/video-player/overlay/base-live-overlay' })\nexport default class BaseVideoLiveOverlay<\n T extends BaseVideoLiveOverlayArgs = BaseVideoLiveOverlayArgs\n> extends BaseOverlay {\n // region Services.\n\n @service declare ajax: AjaxService;\n @service declare notificationManager: NotificationManager;\n @service declare intl: ADCIntlService;\n\n // endregion\n\n // Overridden Properties.\n\n /** @override */\n get canStreamVideo(): boolean {\n return ![NoPermissions, StreamNotAvailable].includes(this.args.errorEnum);\n }\n\n // endregion\n\n // region Player States.\n\n @equal('args.playerState', DISCONNECTED_STATE)\n declare isDisconnected: boolean;\n\n @or('args.isPlaying', 'args.isFrozen')\n declare isPlayingOrFrozen: boolean;\n\n // endregion\n\n /**\n * The current preset ID stored in the camera.\n */\n currentPreset?: string;\n\n /**\n * The dimensions of the player.\n *\n */\n playerDimensions?: { height: number; width: number };\n\n /** @override */\n @action async reportStreamingErrorToWaveFront(): Promise {\n const { errorEnum } = this.args,\n task = this.logFinalPlayerError;\n\n // If previous attempts were failures but the player has now connected, cancel the log task\n if (this.args.errorEnum !== NoError && !this.isDisconnected) {\n task.cancelAll();\n } else if (this.isDisconnected && errorEnum !== NoError) {\n task.perform(FailureLogTimeoutMilliseconds);\n }\n }\n\n /**\n * Task for logging the player error.\n *\n * @param timeoutMs time before the message is logged.\n */\n logFinalPlayerError = task({ drop: true }, async (timeoutMs: number) => {\n // Wait for the timeout to expire before trying to log the error. This gives time for the player to\n // retry. If the player connects successfully before the timeout, this task will be cancelled.\n await timeout(timeoutMs);\n\n await this.stats.logPlayerError(this.args.errorEnum);\n });\n}\n","import { precompileTemplate } from \"@ember/template-compilation\";\nexport default precompileTemplate(\"\\n \\n \\n\",{ moduleName: \"customer-site/components/svg-paths/icn-view-threesixty-full/index.hbs\" })","/* import __COLOCATED_TEMPLATE__ from './index.hbs'; */\nimport templateOnlyComponent from '@ember/component/template-only';\n\nconst IcnView360Full = templateOnlyComponent<{ Element: SVGElement }>();\n\n/**\n * Modified svg with paths with classes of \"background\" and \"stroke\"\n *\n * See:\n * Glyph-SVG/video/icn-view-360-full-active.svg\n * Glyph-SVG/video/icn-view-360-full-inactive.svg\n */\nexport default IcnView360Full;\n\ndeclare module '@glint/environment-ember-loose/registry' {\n export default interface Registry {\n 'svg-paths/icn-view-threesixty-full': typeof IcnView360Full;\n }\n}\n","import { precompileTemplate } from \"@ember/template-compilation\";\nexport default precompileTemplate(\"\\n \\n \\n\",{ moduleName: \"customer-site/components/svg-paths/icn-view-threesixty-half-pano/index.hbs\" })","/* import __COLOCATED_TEMPLATE__ from './index.hbs'; */\nimport templateOnlyComponent from '@ember/component/template-only';\n\nconst IcnView360HalfPano = templateOnlyComponent<{ Element: SVGElement }>();\n\n/**\n * Modified svg with paths with classes of \"background\" and \"stroke\"\n *\n * See:\n * Glyph-SVG/video/icn-view-360-half-pano-active.svg\n * Glyph-SVG/video/icn-view-360-half-pano-inactive.svg\n */\nexport default IcnView360HalfPano;\n\ndeclare module '@glint/environment-ember-loose/registry' {\n export default interface Registry {\n 'svg-paths/icn-view-threesixty-half-pano': typeof IcnView360HalfPano;\n }\n}\n","import { precompileTemplate } from \"@ember/template-compilation\";\nexport default precompileTemplate(\"\\n \\n \\n\",{ moduleName: \"customer-site/components/svg-paths/icn-view-threesixty-interactive/index.hbs\" })","/* import __COLOCATED_TEMPLATE__ from './index.hbs'; */\nimport templateOnlyComponent from '@ember/component/template-only';\n\nconst IcnView360Interactive = templateOnlyComponent<{ Element: SVGElement }>();\n\n/**\n * Modified svg with paths with classes of \"background\" and \"stroke\"\n *\n * See:\n * Glyph-SVG/video/icn-view-360-interactive-active.svg\n * Glyph-SVG/video/icn-view-360-interactive-inactive.svg\n */\nexport default IcnView360Interactive;\n\ndeclare module '@glint/environment-ember-loose/registry' {\n export default interface Registry {\n 'svg-paths/icn-view-threesixty-interactive': typeof IcnView360Interactive;\n }\n}\n","import { precompileTemplate } from \"@ember/template-compilation\";\nexport default precompileTemplate(\"\\n \\n \\n \\n \\n \\n \\n \\n \\n\",{ moduleName: \"customer-site/components/svg-paths/icn-view-threesixty-two-pano/index.hbs\" })","/* import __COLOCATED_TEMPLATE__ from './index.hbs'; */\nimport templateOnlyComponent from '@ember/component/template-only';\n\nconst IcnView360TwoPano = templateOnlyComponent<{ Element: SVGElement }>();\n\n/**\n * Modified svg with paths with classes of \"background\" and \"stroke\"\n *\n * See:\n * Glyph-SVG/video/icn-view-360-2-pano-active.svg\n * Glyph-SVG/video/icn-view-360-2-pano-inactive.svg\n */\nexport default IcnView360TwoPano;\n\ndeclare module '@glint/environment-ember-loose/registry' {\n export default interface Registry {\n 'svg-paths/icn-view-threesixty-two-pano': typeof IcnView360TwoPano;\n }\n}\n","import { precompileTemplate } from \"@ember/template-compilation\";\nexport default precompileTemplate(\"
\\n {{tc this \\'viewMode\\'}}\\n {{t \\\"generic.video.panTiltZoomSlashDelimited\\\"}}\\n
\\n {{#each this.fisheyeModeBtns as |btn|}}\\n \\n \\n

{{tc this btn.label}}

\\n \\n {{/each}}\\n
\\n \\n
\",{ moduleName: \"customer-site/components/video/video-player/overlay/dewarping-selector-panel/index.hbs\" })","/* import __COLOCATED_TEMPLATE__ from './index.hbs'; */\nimport Component from '@glimmer/component';\nimport { action } from '@ember/object';\nimport { inject as service } from '@ember/service';\nimport IcnViewThreesixtyFull from 'customer-site/components/svg-paths/icn-view-threesixty-full';\nimport IcnViewThreesixtyHalfPano from 'customer-site/components/svg-paths/icn-view-threesixty-half-pano';\nimport IcnViewThreesixtyInteractive from 'customer-site/components/svg-paths/icn-view-threesixty-interactive';\nimport IcnViewThreesixtyTwoPano from 'customer-site/components/svg-paths/icn-view-threesixty-two-pano';\nimport { PLAYING_STATE, READY_STATE } from 'customer-site/enums/VideoPlayerStateEnum';\nimport { syncDewarpConfig } from 'customer-site/models/video/dewarp-config';\nimport { intlPath } from '@adc/i18n/path';\nimport { FisheyeMode } from '@oecommon/oscar-js';\n\nimport './_style.scss';\nimport type { PtzButtonsArgs } from '@adc/ui-components/components/ptz-buttons';\nimport type OespPlaybackStateController from '@adc/video-player/classes/state-controllers/oesp-playback-state-controller';\nimport type { Registry as ServiceRegistry } from '@ember/service';\nimport type DewarpConfig from 'customer-site/models/video/dewarp-config';\n\n/**\n * The default amount to pan.\n */\nconst PanDelta = 10;\n\n/**\n * The default amount to zoom.\n */\nconst ZoomDelta = 0.1;\n\nexport type DewarpingSelectorPanelArgs = {\n apexId?: string;\n dewarpConfig: DewarpConfig;\n playbackStateController?: OespPlaybackStateController;\n playerState: number;\n togglePanTiltOptions?: VoidFunction;\n} & PtzButtonsArgs;\n\ninterface DewarpingSelectorPanelSignature {\n Element: HTMLElement;\n Args: DewarpingSelectorPanelArgs;\n Blocks: {\n default: [];\n };\n}\n\n@intlPath({ path: 'video/video-player/overlay/dewarping-selector-panel' })\nexport default class DewarpingSelectorPanel extends Component {\n //#region Services and Constants\n\n @service declare intl: ServiceRegistry['adc-intl'];\n @service declare identityManager: ServiceRegistry['identity-manager'];\n\n /**\n * The content used for each fisheye mode button.\n */\n readonly fisheyeModeBtns = [\n {\n mode: FisheyeMode.Original,\n label: 'standard360Degrees',\n component: IcnViewThreesixtyFull\n },\n {\n mode: FisheyeMode.Panorama,\n label: 'panoramic',\n component: IcnViewThreesixtyHalfPano\n },\n {\n mode: FisheyeMode.SplitPanorama,\n label: '2x180Degrees',\n component: IcnViewThreesixtyTwoPano\n },\n {\n mode: FisheyeMode.Ptz,\n label: 'interactive',\n component: IcnViewThreesixtyInteractive\n }\n ] as const;\n\n //#endregion Services and Constants\n\n /**\n * Is there video currently shown to the user?\n * Relevant for whether the user can change fisheye modes or to use PTZ in interactive mode.\n */\n get isVideoVisible(): boolean {\n // READY_STATE included for interacting with paused video.\n return [PLAYING_STATE, READY_STATE].includes(this.args.playerState);\n }\n\n /**\n * Is the user in interactive mode?\n */\n get isInInteractiveMode(): boolean {\n return this.fisheyeMode === FisheyeMode.Ptz;\n }\n\n /**\n * The active fisheye mode.\n */\n get fisheyeMode(): FisheyeMode | undefined {\n const { apexId, playbackStateController } = this.args;\n if (!apexId || !playbackStateController) {\n return;\n }\n\n return playbackStateController.fisheyeModes.get(apexId);\n }\n\n /**\n * The actions used for PTZ controls when in interactive mode.\n */\n get interactiveModeActions(): PtzButtonsArgs['actions'] {\n const { apexId, playbackStateController, dewarpConfig } = this.args;\n\n // Method that validates the parameters for an action exist before running the action.\n const validateParams = (\n id: string | undefined,\n controller: OespPlaybackStateController | undefined,\n action: (id: string, controller: OespPlaybackStateController) => void\n ) => {\n if (id && controller) {\n action(id, controller);\n syncDewarpConfig.call(this, dewarpConfig, id, controller);\n }\n };\n\n // Method to create a validated action lambda using apexId and playbackStateController\n const createAction = (action: (id: string, controller: OespPlaybackStateController) => void) => () =>\n validateParams(apexId, playbackStateController, action);\n\n return {\n panUp: createAction((id, controller) => controller.adjustFisheyePanTiltForApexId(id, 0, PanDelta)),\n panDown: createAction((id, controller) => controller.adjustFisheyePanTiltForApexId(id, 0, -PanDelta)),\n panLeft: createAction((id, controller) => controller.adjustFisheyePanTiltForApexId(id, -PanDelta, 0)),\n panRight: createAction((id, controller) => controller.adjustFisheyePanTiltForApexId(id, PanDelta, 0)),\n zoomIn: createAction((id, controller) => controller.adjustFisheyeZoomForApexId(id, ZoomDelta)),\n zoomOut: createAction((id, controller) => controller.adjustFisheyeZoomForApexId(id, -ZoomDelta)),\n resetZoom: createAction((id, controller) => controller.resetFisheyePanTiltZoomForApexId(id))\n };\n }\n\n /**\n * The disabled button used for PTZ controls when in interactive mode.\n */\n get interactiveModeDisabledButtons(): PtzButtonsArgs['disabledButtons'] {\n const isDisabled = !this.isVideoVisible;\n return {\n down: isDisabled,\n left: isDisabled,\n reset: isDisabled,\n right: isDisabled,\n up: isDisabled,\n zoomIn: isDisabled,\n zoomOut: isDisabled\n };\n }\n\n /**\n * Sets the current fisheye mode.\n */\n @action setFisheyeMode(mode: FisheyeMode): void {\n const { apexId, playbackStateController, dewarpConfig } = this.args;\n if (!apexId || !playbackStateController) {\n return;\n }\n\n playbackStateController.setFisheyeMode(apexId, mode);\n\n // Apply the user's last fisheye PTZ settings\n if (mode === FisheyeMode.Ptz) {\n const { lastPan, lastTilt, lastFov } = this.args.dewarpConfig;\n if (lastPan !== null && lastTilt !== null && lastFov !== null) {\n playbackStateController.setFisheyePanTiltZoomForApexId(apexId, lastPan, lastTilt, lastFov);\n }\n }\n\n // Close parent popover menu when mode changes.\n this.args.togglePanTiltOptions?.();\n\n // And reset the applied zoom transform from digital zoom\n this.args.actions.resetZoom();\n\n // Sync dewarp config.\n syncDewarpConfig.call(this, dewarpConfig, apexId, playbackStateController);\n }\n}\n\ndeclare module '@glint/environment-ember-loose/registry' {\n export default interface Registry {\n 'Video::VideoPlayer::Overlay::DewarpingSelectorPanel': typeof DewarpingSelectorPanel;\n }\n}\n","import { precompileTemplate } from \"@ember/template-compilation\";\nexport default precompileTemplate(\"\\n
\\n {{tc this \\'dragToReorder\\'}}\\n
\\n
\\n {{#each this.presetNumbers as |number|}}\\n
\\n {{number}}\\n
\\n {{/each}}\\n
\\n\\n \\n \\n {{#each this.presets as |preset|}}\\n
\\n \\n

{{preset.presetName}}

\\n \\n
\\n {{/each}}\\n
\\n {{#each this.emptyPresets as |emptyPreset|}}\\n
\\n

{{emptyPreset}}

\\n
\\n {{/each}}\\n \\n
\\n
\\n\",{ moduleName: \"customer-site/components/modals/video/edit-onvif-ptz-presets/index.hbs\" })","/* import __COLOCATED_TEMPLATE__ from './index.hbs'; */\nimport Component from '@glimmer/component';\nimport { cached, tracked } from '@glimmer/tracking';\nimport { action } from '@ember/object';\nimport { inject as service } from '@ember/service';\nimport { task, timeout } from 'ember-concurrency';\nimport { intlPath } from '@adc/i18n/path';\n\nimport './_style.scss';\nimport type { DragulaEventName } from '@adc/drag-drop/components/ember-dragula';\nimport type { Registry as ServiceRegistry } from '@ember/service';\nimport type OnvifPtzPreset from 'customer-site/models/video/onvif-ptz-preset';\nimport type { DragulaOptions } from 'dragula';\nimport type { Task } from 'ember-concurrency';\n\n/**\n * The max number of presets.\n */\nconst PresetLimit = 5;\n\ninterface EditOnvifPtzPresetsSignature {\n Args: {\n model: {\n presets: OnvifPtzPreset[];\n savePresets: (presets: OnvifPtzPreset[]) => void;\n deletePreset: (preset: OnvifPtzPreset) => void;\n };\n };\n}\n\n@intlPath({ path: 'modals/video/edit-onvif-ptz-presets' })\nexport default class EditOnvifPtzPresets extends Component {\n @service declare intl: ServiceRegistry['adc-intl'];\n\n /**\n * Our local presets with their own unsaved ordering.\n */\n @tracked _localPresets?: OnvifPtzPreset[];\n\n /**\n * Gets presets to render.\n */\n @cached\n get presets(): OnvifPtzPreset[] {\n return this._localPresets ?? [...this.args.model.presets];\n }\n\n /**\n * Set local presets.\n */\n set presets(presets: OnvifPtzPreset[]) {\n this._localPresets = presets;\n }\n\n /**\n * The preset we are in the process of deleting.\n */\n @tracked presetToBeDeleted?: OnvifPtzPreset;\n\n /**\n * The index of the element being dragged.\n */\n dragIndex?: number;\n\n /**\n * The Dragula config.\n */\n get dragulaConfig(): { options: DragulaOptions; enabledEvents: DragulaEventName[] } {\n return {\n options: {\n copy: false,\n direction: 'vertical',\n moves: (_el: Element, _source: Element, handle: Element) => {\n if (this.deletePresetTask.isRunning) {\n return false;\n }\n\n return handle.classList.contains('handle');\n }\n },\n enabledEvents: ['drag', 'dragend']\n };\n }\n\n /**\n * The preset numbering.\n */\n @cached\n get presetNumbers(): number[] {\n return Array.from({ length: PresetLimit }, (_, i) => i + 1);\n }\n\n /**\n * Empty presets used to fill up unused preset slots.\n */\n @cached\n get emptyPresets(): string[] {\n const name = this.intl.tc(this, 'empty');\n const amount = PresetLimit - this.presets.length;\n const items = Array.from({ length: amount }, () => name);\n return items;\n }\n\n /**\n * Records the index of the element we are dragging.\n */\n @action setDragIndex(el: HTMLElement, source: HTMLElement): void {\n const children = Array.from(source.children).filter((child) => child.hasAttribute('data-id'));\n const index = children.indexOf(el);\n this.dragIndex = index;\n }\n\n /**\n * Syncs presets with what is rendered in the DOM.\n */\n @action syncPresets(el: HTMLElement): void {\n const parent = el.parentElement;\n if (!parent) {\n return;\n }\n\n const children = Array.from(parent.children).filter((child) => child.hasAttribute('data-id'));\n const index = children.indexOf(el);\n if (this.dragIndex === undefined || index === undefined) {\n return;\n }\n\n this.reorderPresets(this.dragIndex, index);\n this.dragIndex = undefined;\n this.presets = [...this.presets];\n }\n /**\n * Fixes up the DOM because which may be incorrect from Ember and dragula interacting.\n */\n @action fixDOM(element: HTMLElement): void {\n const elementForId = new Map();\n const children = Array.from(element.children) as HTMLElement[];\n\n children.forEach((child) => {\n if (!child.hasAttribute('data-id')) {\n child.remove();\n return;\n }\n\n const id = child.dataset.id;\n const itemWithId = this.presets.find((preset) => preset.id === id);\n\n if (!itemWithId) {\n child.remove();\n return;\n }\n\n elementForId.set(id, child);\n });\n\n this.presets.forEach((preset) => {\n const child = elementForId.get(String(preset.id));\n if (child) {\n element.appendChild(child);\n }\n });\n }\n\n /**\n * Reorder presets by moving a preset from its starting to end position.\n */\n @action reorderPresets(initialIndex: number, newIndex: number): void {\n const [preset] = this.presets.splice(initialIndex, 1);\n this.presets.splice(newIndex, 0, preset);\n this.presets = [...this.presets];\n }\n\n /**\n * Sample delete preset.\n */\n @action async deletePreset(preset: OnvifPtzPreset): Promise {\n try {\n // Simulate deletion request\n await this.deletePresetTask.perform(preset);\n\n // Remove preset from parent\n this.args.model.deletePreset(preset);\n\n // Remove preset from local list.\n const index = this.presets.indexOf(preset);\n if (index !== -1) {\n this.presets.splice(index, 1);\n this.presets = [...this.presets];\n }\n } catch (e) {\n console.log(e);\n }\n }\n\n /**\n * Sample save presets.\n */\n @action async savePresets(): Promise {\n await timeout(2000);\n this.args.model.savePresets(this.presets);\n }\n\n /**\n * Sample deletion task\n */\n deletePresetTask: Task = task(\n { drop: true },\n async (preset: OnvifPtzPreset): Promise => {\n this.presetToBeDeleted = preset;\n await timeout(2_000);\n this.presetToBeDeleted = undefined;\n }\n );\n}\n\ndeclare module '@glint/environment-ember-loose/registry' {\n export default interface Registry {\n 'Modals::Video::EditOnvifPtzPresets': typeof EditOnvifPtzPresets;\n }\n}\n","import { precompileTemplate } from \"@ember/template-compilation\";\nexport default precompileTemplate(\"\\n
\\n \\n \\n

{{t \\'generic.video.ptzPresets.presetsUsed\\' count=0}}

\\n
\\n\",{ moduleName: \"customer-site/components/modals/video/new-onvif-ptz-preset/index.hbs\" })","/* import __COLOCATED_TEMPLATE__ from './index.hbs'; */\nimport Component from '@glimmer/component';\nimport { intlPath } from '@adc/i18n/path';\n\nimport './_style.scss';\n\ninterface NewOnvifPtzPresetSignature {\n Element: HTMLDivElement;\n Args: [];\n}\n\n@intlPath({ path: 'modals/video/new-onvif-ptz-preset' })\nexport default class NewOnvifPtzPreset extends Component {}\n\ndeclare module '@glint/environment-ember-loose/registry' {\n export default interface Registry {\n 'Modals::Video::NewOnvifPtzPreset': typeof NewOnvifPtzPreset;\n }\n}\n","import { precompileTemplate } from \"@ember/template-compilation\";\nexport default precompileTemplate(\"
\\n {{t \\'generic.video.ptzPresets.cameraPresets\\'}}\\n {{t \\'generic.video.panTiltZoomSlashDelimited\\'}}\\n
\\n {{#each this.sortedPresets as |preset idx|}}\\n \\n
\\n {{math \\'+\\' idx 1}}\\n
\\n

{{preset.presetName}}

\\n \\n {{/each}}\\n \\n
\\n
\\n \\n\\n \\n
\\n
\",{ moduleName: \"customer-site/components/video/video-player/overlay/onvif-ptz-panel/index.hbs\" })","/* import __COLOCATED_TEMPLATE__ from './index.hbs'; */\nimport Component from '@glimmer/component';\nimport { tracked } from '@glimmer/tracking';\nimport { action } from '@ember/object';\nimport { inject as service } from '@ember/service';\nimport { task } from 'ember-concurrency';\nimport EditOnvifPtzPresets from 'customer-site/components/modals/video/edit-onvif-ptz-presets';\nimport NewOnvifPtzPreset from 'customer-site/components/modals/video/new-onvif-ptz-preset';\nimport { intlPath } from '@adc/i18n/path';\n\nimport './_style.scss';\nimport type { PtzButtonsArgs } from '@adc/ui-components/components/ptz-buttons';\nimport type OespPlaybackStateController from '@adc/video-player/classes/state-controllers/oesp-playback-state-controller';\nimport type { Registry as ServiceRegistry } from '@ember/service';\nimport type Camera from 'customer-site/models/video/devices/camera';\nimport type OnvifPtzPreset from 'customer-site/models/video/onvif-ptz-preset';\nimport type { Task } from 'ember-concurrency';\n\ninterface OnvifPtzPanelSignature {\n Element: HTMLElement;\n Args: PtzButtonsArgs & {\n camera: Camera;\n apexId?: string;\n playbackStateController?: OespPlaybackStateController;\n };\n Blocks: {\n default: [];\n };\n}\n\n/**\n * The ONVIF PTZ UI shown in the PTZ Popover Menu.\n *\n * Based off of the DewarpingSelectorPanel but not identically-styled or identically-implemented.\n */\n@intlPath({ path: 'video/video-player/overlay/onvif-ptz-panel' })\nexport default class OnvifPtzPanel extends Component {\n @service declare modals: ServiceRegistry['modals'];\n @service('video.onvif-ptz-preset-manager')\n declare onvifPtzPresetManager: ServiceRegistry['video/onvif-ptz-preset-manager'];\n\n /**\n * The currently selected preset index.\n */\n @tracked presetIndex: number | null = null;\n\n /**\n * The id for our camera.\n */\n get cameraId(): string {\n return this.args.camera.id;\n }\n\n /**\n * The presets for our camera.\n */\n get presets(): OnvifPtzPreset[] {\n return this.onvifPtzPresetManager.presetsByCameraId.get(this.cameraId) ?? [];\n }\n\n /**\n * The sorted presets for our camera.\n */\n get sortedPresets(): OnvifPtzPreset[] {\n return [...this.presets].sort((a, b) => a.position - b.position);\n }\n\n /**\n * Saves the presets.\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n @action savePresets(_reorderedPresets: OnvifPtzPreset[]): void {\n const selectedPreset = this.presetIndex === null ? null : this.sortedPresets[this.presetIndex];\n\n // TODO(ywang): trigger rerender using reorderedPresets, before we reassigned the tracked presets - this.presets = [...reorderedPresets];\n\n if (selectedPreset) {\n const newIndex = this.presets.indexOf(selectedPreset);\n this.presetIndex = newIndex !== -1 ? newIndex : null;\n } else {\n this.presetIndex = null;\n }\n }\n\n /**\n * Deletes a preset.\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n @action deletePreset(_preset: OnvifPtzPreset): void {\n const selectedPreset = this.presetIndex === null ? null : this.presets[this.presetIndex];\n\n // TODO(ywang): trigger rerender using reorderedPresets, before we reassigned the tracked presets - this.presets = this.presets.filter((p) => p !== preset);\n\n if (selectedPreset) {\n const newIndex = this.presets.indexOf(selectedPreset);\n this.presetIndex = newIndex !== -1 ? newIndex : null;\n } else {\n this.presetIndex = null;\n }\n }\n\n /**\n * Select a preset by index.\n */\n @action selectPresetByIndex(presetIndex: number): void {\n this.gotoPreset.perform(presetIndex);\n }\n\n /**\n * Opens the \"New Preset\" Modal.\n */\n @action openNewPresetModal(): void {\n // TODO(ywang): ensure new ONVIF preset is added to this.presets.\n this.modals.showModal(NewOnvifPtzPreset);\n }\n\n /**\n * Opens the \"Edit Presets\" Modal.\n */\n @action openEditPresetsModal(): void {\n const { sortedPresets, savePresets, deletePreset } = this;\n this.modals.showModal(EditOnvifPtzPresets, {\n presets: sortedPresets,\n savePresets,\n deletePreset\n } satisfies EditOnvifPtzPresets['args']['model']);\n }\n\n /**\n * Task to select a preset by index.\n */\n gotoPreset: Task = task({ restartable: true }, async (presetIndex: number) => {\n const { apexId, playbackStateController } = this.args;\n if (!apexId || !playbackStateController) {\n return;\n }\n\n const preset = this.sortedPresets[presetIndex];\n const ptzController = playbackStateController.getPtzControllerForApexId(apexId);\n if (!ptzController) {\n return;\n }\n\n await ptzController.gotoPreset(apexId, preset.presetNumber);\n this.presetIndex = presetIndex;\n });\n}\n\ndeclare module '@glint/environment-ember-loose/registry' {\n export default interface Registry {\n 'Video::VideoPlayer::Overlay::OnvifPtzPanel': typeof OnvifPtzPanel;\n }\n}\n","import { precompileTemplate } from \"@ember/template-compilation\";\nexport default precompileTemplate(\"\\n {{#if @dewarpConfig}}\\n \\n {{else if @isUsingOespPhysicalPtz}}\\n \\n {{else}}\\n \\n {{#if @panTiltButtonsArePhysical}}\\n
\\n {{#each @camera.panTiltPresets as |preset|}}\\n \\n \\n \\n {{#if (eq preset.id @currentPreset)}}\\n \\n {{/if}}\\n \\n {{/each}}\\n {{#if @canManagePresets}}\\n \\n {{/if}}\\n
\\n {{/if}}\\n {{/if}}\\n
\",{ moduleName: \"customer-site/components/video/video-player/overlay/ptz-popover-menu/index.hbs\" })","/* import __COLOCATED_TEMPLATE__ from './index.hbs'; */\nimport templateOnlyComponent from '@ember/component/template-only';\n\nimport './_style.scss';\nimport type { PopoverMenuSignature } from '@adc/ui-components/components/popover-menu';\nimport type Camera from 'customer-site/models/video/devices/camera';\nimport type DewarpConfig from 'customer-site/models/video/dewarp-config';\nimport type { DewarpingSelectorPanelArgs } from '../dewarping-selector-panel/index';\n\ntype PtzPopoverMenuArgs = Pick & {\n camera: Camera;\n canManagePresets: boolean;\n currentPreset?: string;\n dewarpConfig: DewarpConfig | null;\n isUsingOespPhysicalPtz: boolean;\n managePanTiltPresets: VoidFunction;\n panTiltButtonsArePhysical: boolean;\n selectPreset?(presetId: string): Promise;\n} & Omit; // dewarpConfig can be null for PtzPopoverMenuArgs\n\ninterface PtzPopoverMenuSignature {\n Args: PtzPopoverMenuArgs;\n Blocks: {\n default: [];\n };\n}\n\nconst PtzPopoverMenu = templateOnlyComponent();\nexport default PtzPopoverMenu;\n\ndeclare module '@glint/environment-ember-loose/registry' {\n export default interface Registry {\n 'Video::VideoPlayer::Overlay::PtzPopoverMenu': typeof PtzPopoverMenu;\n }\n}\n","import { precompileTemplate } from \"@ember/template-compilation\";\nexport default precompileTemplate(\"
\\n \\n\\n
\\n {{#if this.showThumbnailSearch}}\\n \\n {{/if}}\\n {{#if @hybridSwapIconToShow}}\\n \\n {{/if}}\\n\\n {{#unless @singlePlayer}}\\n \\n {{/unless}}\\n
\\n\\n {{#if @avsResultSwitchAbility.canGoToPreviousClip}}\\n \\n \\n
\\n {{/if}}\\n {{#if @avsResultSwitchAbility.canGoToNextClip}}\\n \\n \\n \\n {{/if}}\\n\\n \\n\\n
\\n
\\n {{#if @showCameraDescription}}\\n

{{@camera.description}}

\\n {{#if @showSystemDescription}}\\n

{{this.systemDescription}}

\\n {{/if}}\\n {{/if}}\\n
\\n \\n {{! If adding attributes to this component, remember to add them to the other PlayerButtons call\\n below in this component }}\\n \\n {{! If adding attributes to this component, remember to add them to the other PlayerButtons call\\n below in this component }}\\n
\\n \\n {{#if @downloadPopoverAnchorSelector}}\\n \\n \\n
\\n {{#if @supportsThumbnailsDownload}}\\n \\n {{/if}}\\n {{#if @supportsClipDownload}}\\n \\n {{/if}}\\n
\\n
\\n \\n {{/if}}\\n \\n {{! If adding attributes to this component, remember to add them to the other PlayerButtons call\\n above in this component }}\\n \\n {{! If adding attributes to this component, remember to add them to the other PlayerButtons call\\n above in this component }}\\n \\n \\n \\n {{#if this.showIdleAudioIcon}}\\n
\\n \\n
\\n {{/if}}\\n\",{ moduleName: \"customer-site/components/video/video-player/overlay/general-overlay-features/index.hbs\" })","/* import __COLOCATED_TEMPLATE__ from './index.hbs'; */\nimport Component from '@glimmer/component';\nimport { tracked } from '@glimmer/tracking';\nimport { isDestroyed } from '@adc/ember-utils/utils/ember-helpers';\nimport { action, computed } from '@ember/object';\nimport { equal, or, and } from '@ember/object/computed';\nimport { inject as service } from '@ember/service';\nimport { isPresent } from '@ember/utils';\nimport { getRelativeDirections } from 'customer-site/components/video/video-player/base-video-player';\nimport {\n CENTER_PTZ_PRESET,\n FULL_PTZ_PRESET,\n CENTER_PRESET_ZOOM_AMOUNT\n} from 'customer-site/components/video/video-player/overlay/base-overlay';\nimport { getSizeStyleClassFromPlayerSize } from 'customer-site/components/video/video-player/overlay/index';\nimport {\n ButtonPixelsWide,\n transitionToSettingsRoute\n} from 'customer-site/components/video/video-player/overlay/player-buttons/index';\nimport { VideoPanTiltSettings } from 'customer-site/enums/CustomerPageUrl';\nimport { PLAYING_STATE } from 'customer-site/enums/VideoPlayerStateEnum';\nimport { isElementViewable } from 'customer-site/utils/dom';\nimport { getContextAwareThumbnailSearchPage } from 'customer-site/video/thumbnail-search/route';\nimport { sentryWithScopeAndWarn } from '@adc/app-infrastructure/utils/sentry';\nimport { AudioRecordingState } from '@oecommon/oscar-js';\nimport { panTilt, zoom } from '../../../../../utils/video/general';\n\nimport type { PlayerSize } from 'customer-site/components/video/video-player/overlay/player-buttons/index';\nimport './_style.scss';\nimport type ADCIntlService from '@adc/i18n/services/adc-intl';\nimport type { PtzButtonsArgs } from '@adc/ui-components/components/ptz-buttons';\nimport type { RelativeDirections } from '@adc/ui-components/components/zoom-pan-overlay';\nimport type OespPlaybackStateController from '@adc/video-player/classes/state-controllers/oesp-playback-state-controller';\nimport type Store from '@ember-data/store';\nimport type { Registry as ServiceRegistry } from '@ember/service';\nimport type { PlayerInfo } from 'customer-site/components/video/video-streaming/video-streaming-features/types';\nimport type { AvsSwitchAbility } from 'customer-site/components/video/video-streaming/video-streaming-players/index';\nimport type { RelativeDirection } from 'customer-site/enums/RelativeDirection';\nimport type Camera from 'customer-site/models/video/devices/camera';\nimport type DewarpConfig from 'customer-site/models/video/dewarp-config';\nimport type AjaxService from 'customer-site/services/ajax';\nimport type ContextManager from 'customer-site/services/context-manager';\nimport type NavigationService from 'customer-site/services/navigation';\nimport type { OEShouldMuteAudioInfo } from '../two-way-audio-buttons/index';\n\nexport type OperatorAudioNotAvailableButtonContents = {\n buttonAction: (areButtonsInPopover: boolean) => void;\n buttonText: string;\n displayButton: boolean;\n streamRetryable: boolean;\n icon: string;\n};\n\ninterface GeneralOverlayFeaturesSignature {\n Args: {\n /** The apex ID of the device if relevant. */\n apexId?: string;\n associatedDevicesAction?: () => void;\n avsResultSwitchAbility?: AvsSwitchAbility;\n /** The camera object that this overlay is for. */\n camera: Camera;\n cameraSpeakerAlreadyInUse: boolean;\n cannotDoBrowserUploadsForOperatorSite: boolean;\n changeCameraAudio(\n shouldMute: boolean,\n volume: number,\n isEnabledAutomaticallyAfterDelay?: boolean,\n cameraWasAutoMuted?: boolean,\n oeSVRShouldMuteAudio?: boolean\n ): void;\n connectUsersMicrophoneAudio?: () => Promise;\n /** The current preset that the camera is set to. */\n currentPreset?: typeof CENTER_PTZ_PRESET | typeof FULL_PTZ_PRESET;\n dewarpConfig: DewarpConfig | null;\n didTwoWayAudioConnectionRefresh: boolean;\n /** The digital zoom pan function that is passed in from the parent component. */\n digitalZoomPan: (direction: RelativeDirection) => void;\n disableTwoWayAudio: boolean;\n /** If the camera buttons popover is open. */\n displayCameraButtonsPopover: boolean;\n disableDownloadButton?: boolean;\n disableVolumeButton: boolean;\n displayPanTiltPopover: boolean;\n downloadClip?: () => void;\n downloadPopoverAnchorSelector?: string;\n downloadPopoverIsOpen?: boolean;\n downloadThumbnails?: () => void;\n /** The buttons that are enabled in the player. from player-buttons.ts */\n enabledButtons: number[];\n enableCameraAudioAfterPauseStarted?: () => void;\n /** If the digital zoom pan feature is enabled. */\n enableDigitalZoomPan: boolean;\n /** Should we force hide the idle audio icon? This is only used with OE Live-View Players when switching master panes. */\n forceHideIdleAudioIcon?: boolean;\n goToAdjacentVideo?: (isForward: boolean) => void;\n goToAvsSearch?: (cameraId: string) => void;\n goToThumbnailSearch?: (cameraId: string) => void;\n hasBlockedMicrophoneAccess: boolean;\n haveReceivedWebrtcStats: boolean;\n hybridSwapIconToShow: string | null;\n isAudioFullDuplex?: boolean;\n isDownloadTaskRunning: boolean;\n isEndToEndStreamUsingTurn?: boolean;\n isLiveVideo: boolean;\n isMicrophoneConnected: boolean;\n isOeStream: boolean;\n isOperatorSite?: boolean;\n isPlayerExpanded: boolean;\n isSelectedForKeyboardPress: boolean;\n isStreamingEndToEnd: boolean;\n hasStreamConnected: boolean;\n isWarningSoundOn: boolean;\n isUploadClipTaskRunning?: boolean;\n lightAction?: () => void;\n lightState?: number;\n makeOverlayVisible: boolean;\n /** Applicable to OpenEye players only. If we should mute the audio for those devices */\n oeShouldMuteAudioInfo: OEShouldMuteAudioInfo | null;\n operatorAudioNotAvailableButtonContents?: OperatorAudioNotAvailableButtonContents;\n operatorLastViewedAction?: (areButtonsInPopover: boolean) => void;\n panTiltPopoverAnchorSelector: string;\n /** The current physical panTilt (x/y) and zoom positions for the selected device. */\n physicalPtzPosition?: PtzPosition | null;\n /** The playback state controller for OESP streams. NOTE: type should be updated to include webrtcStateController in VID-71053 */\n playbackStateController?: OespPlaybackStateController;\n player: PlayerInfo;\n playerSize: PlayerSize;\n /** The state of the player (playing, paused, etc). From base-video-player.js */\n playerState: number;\n requestRecording?: (buttonAnimation: Promise) => void;\n retryEndToEndWithAudioRequest: () => void;\n saveSnapshot?: (buttonAnimation: Promise) => void;\n selectCameraWithLargeHybridCamera: () => void;\n selectPreset?: (preset: string) => Promise;\n setForceShowOverlayForVolumeSlider?: (forceShow: boolean) => void;\n shouldShowMicrophoneConnectionSpinner: boolean;\n showCameraDescription: boolean;\n showDownloadPopover?: (useDownloadAnchor: boolean) => void;\n showSystemDescription: boolean;\n singlePlayer: boolean;\n supportsClipDownload?: boolean;\n supportsMicrophone: boolean;\n supportsThumbnailsDownload?: boolean;\n supportsThumbnailSearch?: boolean;\n /** If the camera supports volume control. */\n supportsVolume: boolean;\n toggleDetailedOsd: () => void;\n toggleDownloadPopover?: () => void;\n toggleFullSize: () => void;\n /** Toggle more options popover. */\n toggleMoreOptions: () => void;\n toggleMuteMicrophone?: () => void;\n /** Toggle the pan tilt zoom popover. */\n togglePanTiltOptions: (usePanTiltAnchor?: boolean) => void;\n updatePtzPosition?: (position: PtzPosition, isPanTilt: boolean) => void;\n warningSoundAction?: (\n areButtonsInPopover: boolean,\n buttonAnimation: Promise\n ) => boolean | Promise;\n zoomPanLimitations?: ZoomPanLimitations;\n };\n Element: HTMLDivElement;\n}\n\ntype DisabledButtons = PtzButtonsArgs['disabledButtons'];\n\nexport type PtzPosition = {\n panTiltX?: number;\n panTiltY?: number;\n zoomLevel?: number;\n};\n\ntype ZoomPanLimitations = {\n canPanLeft: boolean;\n canPanRight: boolean;\n canPanUp: boolean;\n canPanDown: boolean;\n canZoomIn: boolean;\n canZoomOut: boolean;\n};\n\n/**\n * The amount to pan-tilt for OESP PTZ.\n */\nconst OespPanTiltAmt = 0.5;\n\n/**\n * The amount to zoom for OESP PTZ.\n */\nconst OespZoomAmt = 0.1;\n\n/**\n * The overlay that fits on top of the player and displays information and buttons\n */\nexport default class GeneralOverlayFeatures extends Component {\n tagName = '';\n\n @service declare ajax: AjaxService;\n @service declare contextManager: ContextManager;\n @service declare store: Store;\n @service declare intl: ADCIntlService;\n @service declare media: ADCResponsiveMediaService;\n @service declare navigation: NavigationService;\n @service declare identityManager: ServiceRegistry['identity-manager'];\n\n classNameInner = 'general-overlay-features';\n\n /**\n * How many pixels of space (wide) are available for the player buttons component to use\n */\n @tracked\n availableButtonSpace = ButtonPixelsWide;\n\n /**\n * Anchor selector for camera buttons popover.\n */\n @computed('args.camera.id')\n get displayCameraButtonsPopoverAnchorSelector(): string {\n return '#player-' + this.args.camera.id + ' .more-options-button';\n }\n\n /**\n * If the Pan and Tilt buttons in the bottom bar control physical panning. (Otherwise they are digital)\n */\n @and('args.{camera.canPanTilt,isLiveVideo}')\n declare panTiltButtonsArePhysical: boolean;\n\n /**\n * If the Zoom buttons in the bottom bar control physical zooming. (Otherwise they are digital)\n */\n @and('args.{camera.canZoom,isLiveVideo}')\n declare zoomButtonsArePhysical: boolean;\n\n /**\n * If all digital PTZ features are disabled. If the camera can do both physical zooming and physical panning they are not needed.\n */\n @and('zoomButtonsArePhysical', 'panTiltButtonsArePhysical')\n declare allDigitalPtzFeaturesDisabled: boolean;\n\n /**\n * Is the player currently playing?\n */\n @equal('args.playerState', PLAYING_STATE)\n declare isPlaying: boolean;\n\n /**\n * Are there any popovers open?\n */\n @or('args.{displayCameraButtonsPopover,displayPanTiltPopover,downloadPopoverIsOpen}')\n declare popoverIsOpen: boolean;\n\n /**\n * Should we show the general overlay features UI?\n */\n @computed('args.makeOverlayVisible', 'popoverIsOpen')\n get showGeneralOverlayFeatures(): boolean {\n return this.args.makeOverlayVisible === true || this.popoverIsOpen === true;\n }\n\n /**\n * The name of the system for the camera\n */\n @computed('args.camera.system.description')\n get systemDescription(): string {\n return this.args.camera.get('system.description') as string;\n }\n\n /**\n * Should we show the idle audio playing UI? This is only relevant for OESPs, which only support audio from one camera on one SVR at a time.\n */\n @computed(\n 'showGeneralOverlayFeatures',\n 'args.{forceHideIdleAudioIcon,oeShouldMuteAudioInfo.shouldMutePlayer,supportsVolume}'\n )\n get showIdleAudioIcon(): boolean {\n if (!this.args.oeShouldMuteAudioInfo || !this.args.supportsVolume || this.args.forceHideIdleAudioIcon) {\n return false;\n }\n\n // this icon is to indicate which audio is playing when not being hovered over,\n // hence the check for showGeneralOverlayFeatures\n return !this.args.oeShouldMuteAudioInfo.shouldMutePlayer && !this.showGeneralOverlayFeatures;\n }\n\n /**\n * The size css class based on the player size\n */\n @computed('args.playerSize')\n get sizeStyleClass(): string {\n return getSizeStyleClassFromPlayerSize(this.args.playerSize);\n }\n\n /**\n * Can the user manage presets?\n */\n @computed()\n get canManagePresets(): boolean {\n // Do not copy this deprecated usage. If you see this, please fix it\n // eslint-disable-next-line @adc/ember/no-context-manager-get-route\n return isPresent(this.contextManager.getRouteItem(VideoPanTiltSettings));\n }\n\n /**\n * Does the camera support thumbnail search and does the user have access to the page?\n */\n @computed('args.supportsThumbnailSearch', 'navigation', 'identityManager.isEnterprise')\n get showThumbnailSearch(): boolean {\n const thumbnailSearchPage = getContextAwareThumbnailSearchPage(this.identityManager.isEnterprise);\n return !!this.args.supportsThumbnailSearch && this.navigation.userHasAccess(thumbnailSearchPage);\n }\n\n /**\n * An object of the relative direction enums\n */\n get relativeDirections(): RelativeDirections {\n return getRelativeDirections();\n }\n\n /**\n * An object of which PTZ buttons should be disabled (visible but unclickable).\n *\n * @returns {null|{panUp: boolean, panDown: boolean, panLeft: boolean, panRight: boolean, zoomIn: boolean, zoomOut: boolean}}\n */\n @computed(\n 'panTiltButtonsArePhysical',\n 'zoomButtonsArePhysical',\n 'args.{currentPreset,playerState,zoomPanLimitations}',\n 'args.physicalPtzPosition.{panTiltX,panTiltY,zoomLevel}'\n )\n get disabledPTZButtons(): DisabledButtons {\n const { args, panTiltButtonsArePhysical, zoomButtonsArePhysical } = this,\n { camera, currentPreset, physicalPtzPosition, playerState, zoomPanLimitations } = args;\n\n // Initialize all variables to disabled and then enable them below.\n const disabledButtons: DisabledButtons = {\n zoomIn: true,\n zoomOut: true,\n left: true,\n right: true,\n up: true,\n down: true,\n reset: true\n };\n\n if (!camera) {\n return disabledButtons;\n }\n\n if (panTiltButtonsArePhysical) {\n const zoomedInEnoughToPanTilt = (physicalPtzPosition?.zoomLevel || 0) >= camera.minZoomLevelForPanTilt;\n\n Object.assign>(disabledButtons, {\n left: !zoomedInEnoughToPanTilt,\n right: !zoomedInEnoughToPanTilt,\n up: !zoomedInEnoughToPanTilt,\n down: !zoomedInEnoughToPanTilt\n });\n } else {\n if (zoomPanLimitations && playerState === PLAYING_STATE) {\n Object.assign>(disabledButtons, {\n left: !zoomPanLimitations.canPanLeft,\n right: !zoomPanLimitations.canPanRight,\n up: !zoomPanLimitations.canPanUp,\n down: !zoomPanLimitations.canPanDown\n });\n }\n }\n\n if (zoomButtonsArePhysical) {\n if (currentPreset === FULL_PTZ_PRESET) {\n disabledButtons.zoomIn = false;\n } else {\n if (physicalPtzPosition) {\n const { panTiltX, panTiltY, zoomLevel } = physicalPtzPosition;\n\n // Currently we only track if the device can't zoom in or out more. We should track the same for pans and tilts.\n // todo VID-42358 needs to be completed for us to accomplish this\n Object.assign>(disabledButtons, {\n zoomIn: zoomLevel === camera.maxZoomLevel,\n zoomOut: !!(zoomLevel === CENTER_PRESET_ZOOM_AMOUNT && (panTiltX || panTiltY))\n });\n }\n\n disabledButtons.reset = false;\n }\n } else {\n if (zoomPanLimitations && playerState === PLAYING_STATE) {\n Object.assign>(disabledButtons, {\n zoomIn: !zoomPanLimitations.canZoomIn,\n zoomOut: !zoomPanLimitations.canZoomOut\n });\n }\n }\n\n if (zoomPanLimitations && zoomPanLimitations.canZoomOut) {\n disabledButtons.reset = false;\n }\n\n return disabledButtons;\n }\n\n /**\n * Digital ptz and physical ADC ptz actions used by ptz buttons.\n */\n get standardPtzActions(): PtzButtonsArgs['actions'] {\n return {\n panUp: this.panTilt.bind(this, this.relativeDirections.up),\n panDown: this.panTilt.bind(this, this.relativeDirections.down),\n panLeft: this.panTilt.bind(this, this.relativeDirections.left),\n panRight: this.panTilt.bind(this, this.relativeDirections.right),\n zoomIn: this.zoom.bind(this, this.relativeDirections.in),\n zoomOut: this.zoom.bind(this, this.relativeDirections.out),\n resetZoom: this.zoom.bind(this, this.relativeDirections.reset)\n };\n }\n\n /**\n * Gets the name of the thumbnail search page.\n */\n get thumbnailSearchName(): string {\n const thumbnailSearchPage = getContextAwareThumbnailSearchPage(this.identityManager.isEnterprise);\n return this.navigation.getRouteItem(thumbnailSearchPage)?.pageTitle ?? '';\n }\n\n /**\n * If we can zoom out with the ptz feature, in the current scenario. (IE we zoomed in currently)\n */\n @computed('disabledPTZButtons.zoomOut')\n get canZoomPtzOut(): boolean {\n return this.disabledPTZButtons?.zoomOut === false;\n }\n\n /**\n * Is the microphone audio recorder in an error state? This is only related to OESP streams.\n * When this is true, the microphone button will display an error tooltip in the 2WA component when it is depressed.\n */\n @computed('args.playbackStateController.audioRecordingState')\n get isMicrophoneAudioInError(): boolean {\n return this.args.playbackStateController?.audioRecordingState === AudioRecordingState.Error;\n }\n\n /**\n * Are we using OESP physical PTZ?\n */\n get isUsingOespPhysicalPtz(): boolean {\n const { isLiveVideo, camera } = this.args;\n const hasPtzEnabled = camera.has3PCPanTilt || camera.has3PCZoom;\n return isLiveVideo && hasPtzEnabled;\n }\n\n /**\n * The PTZ actions for OESP PTZ.\n */\n get oespPtzActions(): PtzButtonsArgs['actions'] {\n return {\n panUp: () => this.handleOespPtz('panUp'),\n panDown: () => this.handleOespPtz('panDown'),\n panLeft: () => this.handleOespPtz('panLeft'),\n panRight: () => this.handleOespPtz('panRight'),\n zoomIn: () => this.handleOespPtz('zoomIn'),\n zoomOut: () => this.handleOespPtz('zoomOut'),\n resetZoom: () => this.handleOespPtz('resetZoom')\n };\n }\n\n /**\n * Handles OESP PTZ for the given action\n */\n private handleOespPtz(action: keyof PtzButtonsArgs['actions']): void {\n const { args } = this,\n { apexId, playbackStateController } = args;\n if (!apexId || !playbackStateController) {\n return;\n }\n\n const ptzController = playbackStateController.getPtzControllerForApexId(apexId);\n if (!ptzController) {\n return;\n }\n\n switch (action) {\n case 'panUp':\n ptzController.panTiltZoom(apexId, { tilt: OespPanTiltAmt });\n break;\n case 'panDown':\n ptzController.panTiltZoom(apexId, { tilt: -OespPanTiltAmt });\n break;\n case 'panLeft':\n ptzController.panTiltZoom(apexId, { pan: -OespPanTiltAmt });\n break;\n case 'panRight':\n ptzController.panTiltZoom(apexId, { pan: OespPanTiltAmt });\n break;\n case 'zoomIn':\n ptzController.panTiltZoom(apexId, { zoom: OespZoomAmt });\n break;\n case 'zoomOut':\n ptzController.panTiltZoom(apexId, { zoom: -OespZoomAmt });\n break;\n case 'resetZoom':\n ptzController.gotoHome(apexId);\n break;\n default:\n action satisfies never;\n return;\n }\n }\n\n /**\n * Are PTZ buttons disabled for OESP PTZ?\n */\n @computed('args.{camera,playerState}', 'isUsingOespPhysicalPtz')\n get oespPtzDisabledButtons(): PtzButtonsArgs['disabledButtons'] {\n const isNotPlaying = this.args.playerState !== PLAYING_STATE;\n if (isNotPlaying) {\n return {\n up: true,\n down: true,\n left: true,\n right: true,\n zoomIn: true,\n zoomOut: true,\n reset: true\n };\n }\n\n if (this.isUsingOespPhysicalPtz) {\n const camera = this.args.camera;\n return {\n up: !camera.has3PCPanTilt,\n down: !camera.has3PCPanTilt,\n left: !camera.has3PCPanTilt,\n right: !camera.has3PCPanTilt,\n zoomIn: !camera.has3PCZoom,\n zoomOut: !camera.has3PCZoom,\n reset: false\n };\n }\n\n // No buttons are disabled\n return {\n up: false,\n down: false,\n left: false,\n right: false,\n zoomIn: false,\n zoomOut: false,\n reset: false\n };\n }\n\n /**\n * Goes to the adjacent AVS video (when in an AVS context)\n */\n @action goToAdjacentVideo(isForward: boolean): void {\n this.args.goToAdjacentVideo?.(isForward);\n }\n\n /**\n * Redirect to the pan tilt settings page for this camera.\n */\n @action managePanTiltPresets(): void {\n const { args, contextManager, store } = this,\n { camera, enabledButtons } = args;\n\n if (!camera) {\n return;\n }\n\n transitionToSettingsRoute(contextManager, store, camera, enabledButtons, VideoPanTiltSettings);\n }\n\n /**\n * Move the camera view up, down, left, or right.\n *\n * @param direction The direction in which we are moving.\n */\n @action panTilt(direction: RelativeDirection): void | Promise {\n if (this.panTiltButtonsArePhysical) {\n return (async () => {\n const panTiltAmounts = await panTilt(this.ajax, this.args.camera, direction);\n\n if (typeof panTiltAmounts === 'boolean' || !panTiltAmounts?.value) {\n sentryWithScopeAndWarn('Did not get expected pan tilt values');\n return;\n }\n\n const { x, y } = panTiltAmounts.value;\n\n this.args.updatePtzPosition?.(\n {\n panTiltX: x,\n panTiltY: y\n },\n true\n );\n })();\n }\n\n this.args.digitalZoomPan?.(direction);\n }\n\n /**\n * Zoom the camera in or out.\n *\n * @param direction the RelativeDirection value\n */\n @action zoom(direction: RelativeDirection): void | Promise {\n if (this.zoomButtonsArePhysical) {\n return (async () => {\n const { args, relativeDirections } = this,\n { currentPreset } = args;\n\n if (\n direction === relativeDirections.reset ||\n (currentPreset === CENTER_PTZ_PRESET && direction === relativeDirections.out)\n ) {\n await this.args.selectPreset?.(FULL_PTZ_PRESET);\n return;\n }\n\n if (currentPreset === FULL_PTZ_PRESET && direction === relativeDirections.in) {\n await this.args.selectPreset?.(CENTER_PTZ_PRESET);\n return;\n }\n\n const zoomAmount = await zoom(this.ajax, this.args.camera, direction);\n\n if (typeof zoomAmount === 'boolean' || !zoomAmount.value) {\n sentryWithScopeAndWarn('Did not get expected zoom values');\n return;\n }\n\n this.args.updatePtzPosition?.(\n {\n zoomLevel: zoomAmount.value.zoom\n },\n false\n );\n })();\n }\n\n this.args.digitalZoomPan?.(direction);\n }\n\n /**\n * Method for when the bottom bar icons div resizes. We track how big the element is (it has flex-grow turned on) so the player buttons\n * component knows how many buttons it is capable of displaying at a given time.\n */\n @action onBottomBarIconsResize(el: HTMLElement): void {\n // TODO: This ignore is an existing deprecation that must be refactored, do not copy this usage\n // eslint-disable-next-line @adc/ember/no-is-destroyed\n if (isDestroyed(this)) {\n return;\n }\n\n this.availableButtonSpace = el.clientWidth;\n }\n\n /**\n * Runs when the player bottom bar updates.\n */\n @action onBottomBarUpdate(): void {\n // Close popover when the bottom bar updates to avoid losing its anchor point.\n if (this.args.downloadPopoverIsOpen && !isElementViewable(this.args.downloadPopoverAnchorSelector || '')) {\n this.args.toggleDownloadPopover?.();\n } else if (\n this.args.displayCameraButtonsPopover &&\n !isElementViewable(this.displayCameraButtonsPopoverAnchorSelector)\n ) {\n this.args.toggleMoreOptions?.();\n } else if (\n this.args.displayPanTiltPopover &&\n !isElementViewable(this.args.panTiltPopoverAnchorSelector || '')\n ) {\n this.args.togglePanTiltOptions?.();\n }\n }\n\n /**\n * Transitions to the thumbnail search page for the camera.\n */\n @action onThumbnailSearchClick(): void {\n this.args.goToThumbnailSearch?.(this.args.camera.id);\n }\n}\n\ndeclare module '@glint/environment-ember-loose/registry' {\n export default interface Registry {\n 'Video::VideoPlayer::Overlay::GeneralOverlayFeatures': typeof GeneralOverlayFeatures;\n }\n}\n","import { precompileTemplate } from \"@ember/template-compilation\";\nexport default precompileTemplate(\"
\\n {{#if @headerText}}\\n \\n {{/if}}\\n
\\n\",{ moduleName: \"customer-site/components/video/video-player/overlay/overlay-border/index.hbs\" })","/* import __COLOCATED_TEMPLATE__ from './index.hbs'; */\nimport Component from '@glimmer/component';\nimport { action } from '@ember/object';\n\nimport './_style.scss';\n\nexport interface OverlayBorderSignature {\n Element: HTMLDivElement;\n Args: {\n headerClickAction?: () => Promise;\n headerIcon?: string;\n headerText?: string;\n headerTitle?: string;\n styleClass: string;\n };\n}\n\n/**\n * @classdesc\n *\n * Component that represents the border around a video player.\n */\nexport default class OverlayBorder extends Component {\n /**\n * on click method for the header\n */\n @action headerClickAction(): boolean {\n this.args.headerClickAction?.();\n return false;\n }\n}\n\ndeclare module '@glint/environment-ember-loose/registry' {\n export default interface Registry {\n 'Video::VideoPlayer::Overlay::OverlayBorder': typeof OverlayBorder;\n }\n}\n","import { precompileTemplate } from \"@ember/template-compilation\";\nexport default precompileTemplate(\"
\\n\\n {{#if this.displayVolumeButton}}\\n {{#if this.enableCameraAudioAfterPause.isRunning}}\\n \\n {{else}}\\n
\\n\\n \\n\\n {{!-- template-lint-disable no-pointer-down-event-binding --}}\\n \\n
\\n {{/if}}\\n {{/if}}\\n\\n {{#if this.displayMicrophoneButton}}\\n {{#if @isAudioFullDuplex}}\\n {{#if @shouldShowMicrophoneConnectionSpinner}}\\n \\n {{else}}\\n \\n {{/if}}\\n {{else}}\\n {{#if @shouldShowMicrophoneConnectionSpinner}}\\n \\n {{else}}\\n {{!-- template-lint-disable no-pointer-down-event-binding --}}\\n \\n {{/if}}\\n \\n {{tc this \\'audioNotAvailable\\'}}\\n \\n {{/if}}\\n \\n {{tc this \\'audioIssueOccurred\\'}}\\n \\n\\n \\n {{tc this \\'microphoneAccessBlocked\\'}}\\n \\n {{/if}}\\n
\",{ moduleName: \"customer-site/components/video/video-player/overlay/two-way-audio-buttons/index.hbs\" })","/* import __COLOCATED_TEMPLATE__ from './index.hbs'; */\nimport Component from '@glimmer/component';\nimport { tracked } from '@glimmer/tracking';\nimport { TAB_CODE, nodeHandlesKeyboardInput } from '@adc/ember-utils/utils/a11y';\nimport { action, computed } from '@ember/object';\nimport { alias, and, equal, or } from '@ember/object/computed';\nimport { guidFor } from '@ember/object/internals';\nimport { inject as service } from '@ember/service';\nimport { timeout, task } from 'ember-concurrency';\nimport { PlayerSize } from 'customer-site/components/video/video-player/overlay/player-buttons/index';\nimport {\n FROZEN_STATE,\n PLAYING_STATE,\n READY_STATE,\n LOADING_STATE,\n INITIALIZING_STATE\n} from 'customer-site/enums/VideoPlayerStateEnum';\nimport { POST } from '@adc/ajax/services/adc-ajax';\nimport { intlPath } from '@adc/i18n/path';\n\nimport './_style.scss';\nimport type DomService from '@adc/ember-utils/services/dom';\nimport type ADCIntlService from '@adc/i18n/services/adc-intl';\nimport type AjaxService from 'customer-site/services/ajax';\nimport type ContextManager from 'customer-site/services/context-manager';\nimport type IdentityManager from 'customer-site/services/identity-manager';\n\ninterface TwoWayAudioButtonsArgs {\n cameraId: string;\n cameraSpeakerAlreadyInUse: boolean;\n changeCameraAudio(\n shouldMute: boolean,\n volume: number,\n isEnabledAutomaticallyAfterDelay?: boolean,\n cameraWasAutoMuted?: boolean,\n oeSVRShouldMuteAudio?: boolean\n ): void;\n connectUsersMicrophoneAudio?(): Promise;\n didTwoWayAudioConnectionRefresh: boolean;\n disableVolumeButton: boolean;\n disableTwoWayAudio: boolean;\n enableCameraAudioAfterPauseStarted?(): void;\n hasBlockedMicrophoneAccess: boolean;\n isAudioFullDuplex?: boolean;\n isLiveVideo: boolean;\n isMicrophoneAudioInError: boolean;\n isMicrophoneConnected: boolean;\n isOeStream: boolean;\n isSelectedForKeyboardPress: boolean;\n oeShouldMuteAudioInfo: OEShouldMuteAudioInfo | null;\n playerSize: number;\n playerState: number;\n setForceShowOverlayForVolumeSlider?(shouldForce: boolean): void;\n shouldShowMicrophoneConnectionSpinner: boolean;\n supportsMicrophone: boolean;\n supportsVolume: boolean;\n toggleMuteMicrophone?(shouldMute: boolean, cameraWasAutoMuted?: boolean, oeSVRShouldMuteAudio?: boolean): void;\n}\n\ninterface TwoWayAudioButtonsSignature {\n Element: HTMLDivElement;\n Args: TwoWayAudioButtonsArgs;\n Blocks: {\n default: [];\n };\n}\n\n/**\n * The delay before expanding the sound button.\n */\nconst SoundButtonExpandDelay = 500;\n\n/**\n * The delay before collapsing the sound button.\n */\nconst SoundButtonCollapseDelay = 2000;\n\n/**\n * The default time we will wait to reenable camera audio in half duplex streams after releasing the microphone button.\n */\nexport const DefaultHalfDuplexReenableAudioTimeoutMs = 2000;\n\n/**\n * Constants for different types of actions.\n */\nconst MouseAction = 0,\n KeyAction = 1,\n TouchAction = 2;\n\n/**\n * Constants for different keyboard keys (will move to a11y repo in VID-52378).\n */\nexport const MKey = 'M',\n SKey = 'S';\n\n/**\n * The default value for the volume slider.\n */\nconst DefaultVolumeSliderValue = 50;\n\n/**\n * Tabbable CSS class (used to check if the element is focused).\n */\nconst TabbableCssClass = 'tabbable';\n\n/**\n * This specifies whether this SVR and camera that should output audio.\n * Note that this setting is only relevant for OESP, which supports audio output from only one camera per SVR.\"\n */\nexport type OEShouldMuteAudioInfo = {\n shouldMutePlayer: boolean;\n shouldMuteSVR: boolean;\n};\n\n// region Private Helpers\n\n/**\n * Instead of listening for mouseup/touchend events on the button (does not apply to keyup), listen anywhere on the document.\n * This is so the user can release audio or finish setting the volume even if their mouse moves off the button.\n *\n * @param usingMicrophoneButton Are we using the microphone button or the volume slider?\n * @param actionType What action type is this (mouse, key, touch)?\n */\nfunction addMouseUpTouchEndDomListener(\n this: TwoWayAudioButtons,\n usingMicrophoneButton: boolean,\n actionType: number\n): void {\n const { dom } = this;\n\n const holdEndEventType = actionType === MouseAction ? 'mouseup' : 'touchend';\n this.holdEndEventId = dom.addListener(this, document, holdEndEventType, () => {\n if (usingMicrophoneButton) {\n handleAudioMicrophoneToggleForHalfDuplex.call(this, false, actionType);\n } else {\n this.isMouseDownOnVolumeSlider = false;\n }\n\n dom.removeListener(this, this.holdEndEventId);\n });\n}\n\n/**\n * Handles changing the camera audio.\n */\nfunction handleChangeCameraAudio(this: TwoWayAudioButtons): void {\n this.hasEnabledSoundFirstTime = true;\n this.isSoundEnabled = !!this.volumeSliderValue;\n this.args.changeCameraAudio(!this.isSoundEnabled, this.volumeSliderValue);\n}\n\n/**\n * Sets the unmutedSliderVolume property.\n */\nfunction setUnmutedSliderVolume(this: TwoWayAudioButtons): void {\n const { volumeSliderValue } = this;\n if (volumeSliderValue) {\n this.unmutedSliderVolume = volumeSliderValue;\n }\n}\n\n/**\n * Enables or disables audio coming from the camera.\n *\n * @param shouldMute Is the new state muted for camera audio?\n * @param volume The new volume for camera audio.\n * @param showAnimation Do we want to show the camera audio animation with this change?\n * @param isEnabledAutomaticallyAfterDelay Is the camera audio being enabled automatically after a delay?\n */\nfunction enableDisableCameraAudio(\n this: TwoWayAudioButtons,\n shouldMute: boolean,\n volume = 0,\n showAnimation = false,\n isEnabledAutomaticallyAfterDelay = false\n): void {\n const { oeShouldMuteAudioInfo } = this.args,\n cameraWasAutoMuted = (oeShouldMuteAudioInfo?.shouldMutePlayer ?? false) && shouldMute,\n camerasSVRWasMuted = oeShouldMuteAudioInfo?.shouldMuteSVR ?? false;\n this.volumeSliderValue = shouldMute ? 0 : volume;\n this.isSoundEnabled = !shouldMute;\n\n this.args.changeCameraAudio?.(\n shouldMute,\n this.volumeSliderValue,\n isEnabledAutomaticallyAfterDelay,\n cameraWasAutoMuted,\n camerasSVRWasMuted\n );\n\n if (showAnimation) {\n this.animateSoundButton.perform();\n }\n}\n\n/**\n * Enables or disables audio sent from the user's microphone to the camera.\n *\n * @param shouldMute Is the new state muted for microphone audio?\n */\nfunction enableDisableMicrophoneAudio(this: TwoWayAudioButtons, shouldMute: boolean): void {\n if (!shouldMute && !this.hasLoggedTalkdownEvent) {\n const url = 'video/streamLogs/webrtcStreamLogs/reportTalkdownInitiated';\n this.ajax.apiRequest(url, undefined, { globalDeviceId: this.args.cameraId }, POST);\n this.hasLoggedTalkdownEvent = true;\n }\n\n const { isAudioFullDuplex, oeShouldMuteAudioInfo } = this.args,\n cameraWasAutoMuted = (oeShouldMuteAudioInfo?.shouldMutePlayer ?? false) && shouldMute && isAudioFullDuplex,\n camerasSVRWasMuted = (oeShouldMuteAudioInfo?.shouldMuteSVR ?? false) && isAudioFullDuplex;\n this.isMicrophoneEnabled = !shouldMute;\n this.args.toggleMuteMicrophone?.(shouldMute, cameraWasAutoMuted, camerasSVRWasMuted);\n}\n\n/**\n * Handles camera audio muting or unmuting for full duplex audio connections.\n *\n * @param shouldMute Is the new state muted for camera audio?\n * @param volume The new volume for camera audio.\n */\nfunction handleAudioMuteToggleForFullDuplex(this: TwoWayAudioButtons, shouldMute: boolean, volume: number): void {\n // If audio hasn't turned on yet but our first button click is camera audio, just turn on camera audio.\n // If our first button were microphone, we'd also turn on camera audio.\n this.hasEnabledSoundFirstTime = true;\n enableDisableCameraAudio.call(this, shouldMute, volume);\n}\n\n/**\n * Handles microphone audio muting or unmuting for full duplex audio connections.\n *\n * @param shouldMute Is the new state muted for microphone audio?\n */\nfunction handleAudioMicrophoneToggleForFullDuplex(this: TwoWayAudioButtons, shouldMute: boolean): void {\n enableDisableMicrophoneAudio.call(this, shouldMute);\n\n // If audio hasn't turned on yet and our first button click is with microphone, also turn on camera audio.\n if (!this.hasEnabledSoundFirstTime) {\n this.hasEnabledSoundFirstTime = true;\n enableDisableCameraAudio.call(this, false, this.volumeSliderValue);\n }\n}\n\n/**\n * Handles microphone audio muting or unmuting for half duplex audio connections.\n *\n * @param isDown Is the mouse/key/touch down on the microphone button to enable audio, as opposed to up?\n * @param actionType The type of action that is used (mouse, key, touch).\n */\nfunction handleAudioMicrophoneToggleForHalfDuplex(this: TwoWayAudioButtons, isDown: boolean, actionType: number): void {\n const { isSoundEnabled } = this;\n\n // While speaking in half duplex, mute camera audio. Then revert that value when we let go of the microphone button.\n if (isDown) {\n // If sound is currently enabled, mute it. No action needed if audio is already muted.\n if (isSoundEnabled) {\n setUnmutedSliderVolume.call(this);\n enableDisableCameraAudio.call(this, true);\n }\n\n // If the sound button disabling task is running, cancel it and revert button state.\n if (this.enableCameraAudioAfterPause.isRunning) {\n this.enableCameraAudioAfterPause.cancelAll();\n }\n\n if (actionType !== KeyAction) {\n addMouseUpTouchEndDomListener.call(this, true, actionType);\n }\n } else {\n // If sound is currently muted, unmute it. Re-enable it after a short pause with a task.\n if (!isSoundEnabled) {\n this.enableCameraAudioAfterPause.perform(!this.hasEnabledSoundFirstTime);\n }\n\n this.hasEnabledSoundFirstTime = true;\n }\n\n // Then enable/disable microphone audio.\n enableDisableMicrophoneAudio.call(this, !isDown);\n}\n\n/**\n * Processes the actions following different two-way audio key presses.\n *\n * @param event The key event.\n * @param isKeyDown Is this a keydown event?\n */\nfunction processKeyPresses(this: TwoWayAudioButtons, event: KeyboardEvent, isKeyDown: boolean): void {\n const { target, key } = event,\n { isSelectedForKeyboardPress } = this.args;\n\n // If the target node already handles keyboard input, ignore.\n // Or, if the camera is not selected for keyboard press, ignore.\n if (nodeHandlesKeyboardInput(target as Node) || !isSelectedForKeyboardPress) {\n return;\n }\n\n switch (key) {\n // For toggling the user's microphone.\n case MKey:\n if (this.args.isMicrophoneConnected) {\n handleAudioMicrophoneToggleForHalfDuplex.call(this, isKeyDown, KeyAction);\n } else {\n this.connectMicrophone();\n }\n\n break;\n // For toggling the camera audio.\n case SKey:\n this.hasEnabledSoundFirstTime = true;\n\n if (isKeyDown) {\n this.toggleCameraAudioMute();\n }\n\n break;\n // For tabbing to the sound button/volume slider and adjusting the camera audio volume.\n case TAB_CODE: {\n this.isSoundButtonNoticeable = document.activeElement?.classList.contains(TabbableCssClass) ?? false;\n break;\n }\n }\n}\n\n/**\n * Mute or unmute the camera audio.\n *\n * @param shouldMute Should the camera audio be muted?\n */\nfunction muteUnmuteCameraAudio(this: TwoWayAudioButtons, shouldMute: boolean): void {\n setUnmutedSliderVolume.call(this);\n\n if (this.args.isAudioFullDuplex) {\n handleAudioMuteToggleForFullDuplex.call(this, shouldMute, this.unmutedSliderVolume);\n } else {\n enableDisableCameraAudio.call(this, shouldMute, this.unmutedSliderVolume);\n }\n}\n\n// endregion\n\n/**\n * @classdesc\n *\n * A component for displaying and maintaining the state of two-way audio buttons within a video player overlay.\n * This supports two types of two-way audio:\n *\n * Half duplex: the user must hold the microphone button to speak - releasing it will mute the mic again.\n * When the microphone button is unmuted, camera audio will automatically mute.\n * Most cameras will use this, unless the camera has specific firmware enhancements for audio.\n *\n * Full duplex: the user clicks the microphone button to mute or unmute, no holding necessary.\n * The user can also speak and hear audio from the camera at the same time.\n * This is possible with certain firmware enhancements on certain camera models.\n *\n * @param {boolean} cameraSpeakerAlreadyInUse Have we detected that the speaker is already in use for this camera?\n * @param {Function(boolean, number): void} changeCameraAudio Function passed for muting/unmuting and changing the volume of the audio coming from the stream.\n * @param {Function(): void} connectUsersMicrophoneAudio Function for requesting microphone permissions for sending user audio.\n * @param {boolean} disableVolumeButton Should the volume button be disabled?\n * @param {boolean} disableTwoWayAudio Should the two way audio buttons be disabled?\n * @param {Function(): void} enableCameraAudioAfterPauseStarted Function passed in to notify the parent component that the camera audio is being enabled after a pause.\n * @param {boolean} hasBlockedMicrophoneAccess Has the user blocked microphone access?\n * @param {boolean} isAudioFullDuplex Is audio full duplex (as opposed to half duplex)?\n * @param {boolean} isLiveVideo Is this a live video stream (as opposed to playback)?\n * @param {boolean} isMicrophoneAudioInError Is the microphone talk-down connection in an error state? (only applies to oesp cameras)\n * @param {boolean} isMicrophoneConnected Is the user's microphone audio connected?\n * @param {boolean} isOeStream Is this an OESP stream/is this a third-party camera (as opposed to an ADC Camera)?\n * @param {number} playerSize The current size of the player and overlay.\n * @param {number} playerState The current state of the player and overlay.\n * @param {Function(boolean): void} setForceShowOverlayForVolumeSlider Function passed to set forceShowOverlayForVolumeSlider in LiveOverlay.\n * @param {Function(boolean): void} setShouldDisableDraggablePlayer Function passed to set shouldDisableDraggablePlayer in VideoStreamingPlayers.\n * @param {boolean} supportsMicrophone Does the player support microphone audio (from user to camera)?\n * @param {boolean} supportsVolume Does the player support audio input from the camera (from camera to user)?\n * @param {Function(boolean): void} toggleMuteMicrophone Function passed for muting/unmuting audio sent from the user's microphone.\n */\n@intlPath({ path: 'video/video-player/overlay/two-way-audio-buttons' })\nexport default class TwoWayAudioButtons extends Component {\n @service declare ajax: AjaxService;\n @service declare contextManager: ContextManager;\n @service declare dom: DomService;\n @service declare identityManager: IdentityManager;\n @service declare intl: ADCIntlService;\n\n // region Properties\n\n /**\n * Is the camera's sound enabled for two-way audio?\n */\n @tracked isSoundEnabled = false;\n\n /**\n * Is the user's microphone sound enabled for two-way audio?\n */\n @tracked isMicrophoneEnabled = false;\n\n /**\n * The id to use for the microphone button so tooltips can attach.\n */\n get microphoneButtonId(): string {\n return `microphone-button-${guidFor(this)}`;\n }\n\n /**\n * Should we display the microphone is blocked message?\n */\n @tracked displayMicrophoneBlockedMessage = false;\n\n /**\n * The volume slider value.\n */\n @tracked volumeSliderValue = DefaultVolumeSliderValue;\n\n /**\n * The unmuted volume slider value (to set the slider when we unmute).\n */\n @tracked unmutedSliderVolume = DefaultVolumeSliderValue;\n\n /**\n * Should the player be muted after it resumes playing?\n * This is to prevent unmutedSliderVolume from being 0,\n * which would break the toggle's functionality.\n */\n @tracked shouldMuteAfterPlayResume = true;\n\n /**\n * Are we holding the mouse down on the volume slider?\n */\n @tracked isMouseDownOnVolumeSlider = false;\n\n /**\n * Have we enabled the sound for the first time?\n * This is true when we first press either the sound or the microphone button for the stream.\n */\n @tracked hasEnabledSoundFirstTime = false;\n\n /**\n * Should we make the sound button noticeable?\n */\n @tracked isSoundButtonNoticeable = false;\n\n /**\n * Have we handled tasks upon microphone connection yet? Only handle tasks once upon microphone connection.\n */\n @tracked hasHandledTasksUponMicrophoneConnection = false;\n\n /**\n * The id for the mouseup/touchend listener on the document.\n * This is added when the user starts a mousedown/touchstart event on the volume slider and the microphone button.\n * We listen for the up/end event anywhere on the document so that we get the correct volume value and\n * so the user can release the button at any location and still disable microphone audio.\n */\n holdEndEventId = '';\n\n /**\n * Has a talkdown event been logged for this stream?\n */\n hasLoggedTalkdownEvent = false;\n\n // region Computed Properties\n\n /**\n * Does this customer have internal beta access? (Currently used for keyboard shortcuts).\n */\n @alias('contextManager.identityModel.hasInternalBetaAccess')\n declare hasInternalBetaAccess: boolean;\n\n /**\n * Are we displaying the volume slider?\n */\n @or('isSoundButtonNoticeable', 'isMouseDownOnVolumeSlider')\n declare displayVolumeSlider: boolean;\n\n /**\n * Should the volume controls be disabled?\n */\n @or('args.disableVolumeButton', 'isFrozenOrReady', 'args.disableTwoWayAudio')\n declare disableVolumeControls: boolean;\n\n /**\n * Is the player currently playing?\n */\n @equal('args.playerState', PLAYING_STATE)\n declare isPlaying: boolean;\n\n /**\n * Is the player currently loading?\n */\n @equal('args.playerState', LOADING_STATE)\n declare isLoading: boolean;\n\n /**\n * Is the player currently frozen?\n */\n @equal('args.playerState', FROZEN_STATE)\n declare isFrozen: boolean;\n\n /**\n * Is the player currently ready (paused)?\n */\n @equal('args.playerState', READY_STATE)\n declare isReady: boolean;\n\n /**\n * Is the player currently initializing?\n */\n @equal('args.playerState', INITIALIZING_STATE)\n declare isInitializing: boolean;\n\n /**\n * Is the player currently in a frozen or ready (paused) state?\n * This is used in various places to check if the player\n * is still connected but not actively playing video.\n */\n @or('isFrozen', 'isReady')\n declare isFrozenOrReady: boolean;\n\n /**\n * Will become true when the stream goes into loading state.\n * Will become false when the stream first starts playing.\n * If true, the audio will be muted when the player state changes to PLAYING\n * If false, it'll stay the same (muted if already muted, and vice versa).\n */\n @tracked hasStreamLoadTriggered = false;\n\n /**\n * Is the player currently playing and is the microphone connected after a player refresh?\n */\n @and('isPlaying', 'args.isMicrophoneConnected', 'args.didTwoWayAudioConnectionRefresh')\n declare isPlayingAndIsMicrophoneConnectedAfterPlayerRefresh: boolean;\n\n /**\n * Should we display the audio issue occurred message?\n */\n @and('args.isMicrophoneAudioInError', 'isMicrophoneEnabled')\n declare displayAudioIssueOccurredMessage: boolean;\n\n /**\n * Should we display the volume button?\n */\n @computed('args.supportsVolume', 'isPlaying', 'isFrozenOrReady')\n get displayVolumeButton(): boolean {\n return this.args.supportsVolume && (this.isPlaying || this.isFrozenOrReady);\n }\n\n /**\n * Should we display the microphone button?\n */\n @computed('args.supportsMicrophone', 'isPlaying', 'isFrozen')\n get displayMicrophoneButton(): boolean {\n return this.args.supportsMicrophone && (this.isPlaying || this.isFrozen);\n }\n\n /**\n * Should the microphone be temporarily disabled after an 'unclick'?\n * Used to prevent spamming of the microphone button (which, depending talkdown\n * communication method being used, may cause talkdown audio to malfunction).\n */\n @computed('args.isOeStream', 'enableCameraAudioAfterPause.isRunning')\n get disableMicrophoneButtonTemporarilyOnDepress(): boolean {\n return this.args.isOeStream && this.enableCameraAudioAfterPause.isRunning;\n }\n\n /**\n * Which SVG should we show for the user's sound button when two-way audio is enabled?\n */\n @computed('isSoundEnabled', 'isFrozenOrReady')\n get soundButtonSvg(): string {\n return this.isSoundEnabled && !this.isFrozenOrReady ? 'sound' : 'sound-mute';\n }\n\n /**\n * The text to use for the sound button based on the current state.\n */\n @computed('isSoundEnabled')\n get soundButtonText(): string {\n return this.intl.tc(this, this.isSoundEnabled ? 'muteAudio' : 'unmuteAudio');\n }\n\n /**\n * Which SVG should we show for the user's microphone toggle button when two-way audio is enabled?\n * This is based on the current audio state and whether this stream uses full- or half-duplex.\n */\n @computed(\n 'args.{isAudioFullDuplex,isMicrophoneConnected}',\n 'displayAudioIssueOccurredMessage',\n 'hasEnabledSoundFirstTime',\n 'isMicrophoneEnabled'\n )\n get microphoneButtonSvg(): string {\n // Here are all of the possible situations for full duplex and half duplex:\n // Both full/half duplex, microphone is not connected: mic-muted\n // Full duplex, no audio buttons pressed yet (camera or user audio): mic\n // Full duplex, user is sending audio: mic\n // Full duplex, user is muted/stopped sending audio: mic-muted\n // Half duplex, user is muted/not sending audio: mic\n // Half duplex, user is sending audio: mic-speak\n // Half duplex, the audio error message is being displayed: mic-muted\n const { hasEnabledSoundFirstTime, isMicrophoneEnabled } = this,\n { isAudioFullDuplex } = this.args;\n\n if (\n (isAudioFullDuplex && hasEnabledSoundFirstTime && !isMicrophoneEnabled) ||\n !this.args.isMicrophoneConnected ||\n (this.displayAudioIssueOccurredMessage && !isAudioFullDuplex)\n ) {\n return 'mic-muted';\n }\n\n if (!isAudioFullDuplex && isMicrophoneEnabled) {\n return 'mic-speak';\n }\n\n return 'mic';\n }\n\n /**\n * The text to use for the microphone button based on the current state.\n */\n @computed('args.{isAudioFullDuplex,isMicrophoneConnected}', 'isMicrophoneEnabled')\n get microphoneButtonText(): string {\n // Here are all of the possible situations for full duplex and half duplex:\n // Full duplex, user is muted: unmuteMicrophone\n // Full duplex, user is sending audio: muteMicrophone\n // Half duplex, user's microphone is connected: holdToTalk\n // Half duplex, user's microphone is not connected: clickToEnable\n const { isMicrophoneEnabled, intl } = this,\n { isAudioFullDuplex, isMicrophoneConnected } = this.args;\n\n let textId;\n\n if (!isAudioFullDuplex) {\n textId = isMicrophoneConnected ? 'holdToTalk' : 'clickToEnable';\n } else {\n textId = isMicrophoneEnabled ? 'muteMicrophone' : 'unmuteMicrophone';\n }\n\n return intl.tc(this, textId);\n }\n\n /**\n * The orientation of the slider.\n */\n @computed('args.playerSize')\n get isSliderVertical(): boolean {\n return ![PlayerSize.XXSmall, PlayerSize.XSmall, PlayerSize.Small].includes(this.args.playerSize);\n }\n\n /**\n * Should we show a message over the microphone button saying that two-way audio may not work?\n * This can occur if a camera is streaming audio with 2+ browsers, not just one, and the speaker is already in use.\n * Do not show this for the operator site, as that site does audio takeovers.\n */\n @computed('args.cameraSpeakerAlreadyInUse', 'identityManager.identityModel.isOperatorSite', 'isMicrophoneEnabled')\n get showCameraSpeakerAlreadyInUseMessage(): boolean {\n if (this.identityManager.identityModel?.isOperatorSite) {\n return false;\n }\n\n return this.isMicrophoneEnabled && this.args.cameraSpeakerAlreadyInUse;\n }\n\n // endregion\n\n // region Tasks\n\n /**\n * A task to disable the sound button then reenable after a short period of time.\n * This is to prevent echoes coming back from half duplex cameras immediately after releasing the microphone button.\n *\n * @param showAnimation Should we show the camera audio button animation when we toggle this button?\n */\n enableCameraAudioAfterPause = task({ restartable: true }, async (showAnimation: boolean) => {\n // We will delay enabling by 2 seconds, or this value can temporarily be customized by url param.\n const urlParams = new URLSearchParams(window.location.search),\n audioDelayParam = urlParams.get('audioDelay') || '',\n timeoutMs = Number.parseInt(audioDelayParam) || DefaultHalfDuplexReenableAudioTimeoutMs;\n\n if (this.args.isOeStream) {\n this.args.enableCameraAudioAfterPauseStarted?.();\n }\n\n await timeout(timeoutMs);\n\n enableDisableCameraAudio.call(this, false, this.unmutedSliderVolume, showAnimation, true);\n });\n\n /**\n * Animate the sound button upon reloading the two-way audio stream after microphone connection.\n */\n animateSoundButton = task({ restartable: true }, async () => {\n await timeout(SoundButtonExpandDelay);\n this.isSoundButtonNoticeable = true;\n this.args.setForceShowOverlayForVolumeSlider?.(true);\n\n await timeout(SoundButtonCollapseDelay);\n this.isSoundButtonNoticeable = false;\n this.args.setForceShowOverlayForVolumeSlider?.(false);\n });\n\n // endregion\n\n // region Actions\n\n /**\n * Action to add a dom listener and set isMouseDownOnVolumeSlider when the user interacts with the volume slider.\n *\n * @param isMouseAction Is this a mouse action (as opposed to a touch action)?\n */\n @action setIsMouseDownOnVolumeSlider(isMouseAction: boolean): void {\n const actionType = isMouseAction ? MouseAction : TouchAction;\n addMouseUpTouchEndDomListener.call(this, false, actionType);\n this.isMouseDownOnVolumeSlider = true;\n }\n\n /**\n * Action to set the camera audio volume upon microphone connection to the volume the user set prior to microphone connection.\n */\n @action handleTasksUponMicrophoneConnection(): void {\n if (this.isPlayingAndIsMicrophoneConnectedAfterPlayerRefresh && !this.hasHandledTasksUponMicrophoneConnection) {\n // If this is an OESP stream (third-party camera), do not enable audio immediately upon microphone connection.\n if (this.args.isOeStream) {\n this.volumeSliderValue = 0;\n this.isSoundEnabled = false;\n return;\n }\n handleChangeCameraAudio.call(this);\n this.animateSoundButton.perform();\n this.hasHandledTasksUponMicrophoneConnection = true;\n }\n }\n\n /**\n * Action when the user adjusts the (camera) sound volume slider for a two-way audio stream.\n */\n @action setCameraAudioVolume(volume: number): void {\n this.volumeSliderValue = volume;\n this.shouldMuteAfterPlayResume = !volume;\n handleChangeCameraAudio.call(this);\n }\n\n /**\n * Action to mute or unmute the camera audio if the user presses the (camera) sound button.\n * This simply toggles between muted and unmuted.\n */\n @action toggleCameraAudioMute(): void {\n const { isSoundEnabled } = this;\n this.shouldMuteAfterPlayResume = isSoundEnabled;\n muteUnmuteCameraAudio.call(this, isSoundEnabled);\n }\n\n /**\n * When: This action will be called when the playerState argument is updated.\n * What: It'll ensure the correct state for the camera audio after user actions\n * such as retry connection, seek in timeline, pause/play, etc.\n */\n @action handleAudioStateOnPlayerStateChange(): void {\n if (this.isLoading) {\n this.hasStreamLoadTriggered = true;\n }\n\n // For OESP live streams, do nothing if the stream is initializing or loading to prevent audio leaks.\n if (this.args.isOeStream && this.args.isLiveVideo && (this.isInitializing || this.isLoading)) {\n return;\n }\n\n const userHasNotEnabledSound = !this.hasEnabledSoundFirstTime;\n const isCurrentlyMuted = !this.isSoundEnabled;\n const isFirstTimePlaying = this.isPlaying && this.hasStreamLoadTriggered;\n const isResumingAndShouldMute = this.isPlaying && this.shouldMuteAfterPlayResume;\n\n const shouldMute =\n // If audio's never been enabled, keep it muted\n userHasNotEnabledSound ||\n // Mute while frozen or paused\n this.isFrozenOrReady ||\n // Always start out with the audio muted\n isFirstTimePlaying ||\n // If it's resuming, but should be muted, mute\n isResumingAndShouldMute;\n\n // Change audio state only if it differs from the current state.\n if (shouldMute !== isCurrentlyMuted) {\n muteUnmuteCameraAudio.call(this, shouldMute);\n\n if (shouldMute) {\n this.hasStreamLoadTriggered = false;\n }\n }\n }\n\n /**\n * Action when the user presses (mouse up or down) the microphone button for a half duplex two-way audio stream.\n * This is used for half duplex only. Full duplex always takes click actions and never mouse/touch events.\n *\n * @param isMouseAction Is this a mouse action (as opposed to a touch action)?\n * @param event The mousedown event.\n */\n @action handleHalfDuplexMicrophonePressStart(isMouseAction: boolean, event: MouseEvent | TouchEvent): void {\n if (!this.args.isMicrophoneConnected) {\n return;\n }\n\n event.preventDefault();\n const actionType = isMouseAction ? MouseAction : TouchAction;\n handleAudioMicrophoneToggleForHalfDuplex.call(this, true, actionType);\n }\n\n /**\n * Connects microphone audio after clicking the microphone button for the first time.\n */\n @action connectMicrophone(): void {\n const microphonePromise = this.args.connectUsersMicrophoneAudio?.();\n microphonePromise?.then(() => {\n this.hasEnabledSoundFirstTime = true;\n this.displayMicrophoneBlockedMessage = false;\n });\n }\n\n /**\n * Handles click actions on the full duplex microphone button.\n */\n @action clickFullDuplexMicrophoneButton(): void {\n // If we haven't connected microphone audio yet, attempt to connect it first.\n if (!this.args.isMicrophoneConnected) {\n this.connectMicrophone();\n return;\n }\n\n handleAudioMicrophoneToggleForFullDuplex.call(this, this.isMicrophoneEnabled);\n }\n\n /**\n * This handler handles oeShouldMuteAudioInfo updating.\n * OE only supports audio from one camera on one SVR at a time,\n * so if we unmute a camera, all the other camera players should be muted.\n */\n @action onOeShouldMuteAudioUpdate(): void {\n // If this is an ADC Camera on the live-view, we do not want to mute the incoming audio.\n // Interacting with 3PC's audio should have no impact on ADC Cameras on the live view.\n if (!this.args.isOeStream && this.args.isLiveVideo) {\n return;\n }\n\n const shouldMutePlayer = this.args.oeShouldMuteAudioInfo?.shouldMutePlayer ?? false;\n\n // If the player should be muted and the microphone is enabled (full-duplex only), mute the microphone.\n if (shouldMutePlayer && this.args.isAudioFullDuplex && this.isMicrophoneEnabled) {\n enableDisableMicrophoneAudio.call(this, true);\n }\n\n // If the player should be muted and sound is enabled, mute the camera audio.\n if (shouldMutePlayer && this.isSoundEnabled) {\n this.shouldMuteAfterPlayResume = !this.isFrozenOrReady;\n muteUnmuteCameraAudio.call(this, true);\n }\n }\n\n /**\n * Handles hover actions over the microphone button (to show or hide the microphone blocked message).\n */\n @action handleMicrophoneButtonHover(isHovering: boolean): void {\n if (!this.args.isMicrophoneConnected && this.args.hasBlockedMicrophoneAccess) {\n this.displayMicrophoneBlockedMessage = isHovering;\n }\n }\n\n /**\n * Add hot keys once the two-way-audio-buttons div is inserted. (Restricted behind internal beta for the time being).\n */\n @action addHotKeys(): void {\n if (this.hasInternalBetaAccess) {\n this.dom.addListener(this, document, 'keydown', (event: KeyboardEvent) =>\n processKeyPresses.call(this, event, true)\n );\n this.dom.addListener(this, document, 'keyup', (event: KeyboardEvent) =>\n processKeyPresses.call(this, event, false)\n );\n }\n }\n\n /**\n * Prevents keyboard events from going back up through the DOM.\n *\n * @param event The keydown event.\n */\n @action preventBubblingKeyboardEvents(event: KeyboardEvent): void {\n event.stopPropagation();\n }\n\n // endregion\n}\n\ndeclare module '@glint/environment-ember-loose/registry' {\n export default interface Registry {\n 'Video::VideoPlayer::Overlay::TwoWayAudioButtons': typeof TwoWayAudioButtons;\n }\n}\n","import { precompileTemplate } from \"@ember/template-compilation\";\nexport default precompileTemplate(\"{{! @glint-nocheck: We need to stop using this date picker, it stinks. }}\\n\\n {{yield section}}\\n\\n\",{ moduleName: \"customer-site/components/modals/date-time-picker/index.hbs\" })","/* import __COLOCATED_TEMPLATE__ from './index.hbs'; */\nimport templateOnlyComponent from '@ember/component/template-only';\n\nimport './_style.scss';\nimport type DatePickerDialog from '@adc/ui-components/components/modals/date/date-picker';\n\nexport interface DateTimePickerModalSignature {\n Element: HTMLDivElement;\n Args: {\n applyText?: string;\n title: string;\n showWarning?: boolean;\n onSelection: (newDate: Date) => void | boolean | Promise;\n model: {\n defaultDate: Date;\n disableDate?: (d: Date) => boolean;\n minDate: Date;\n maxDate: Date;\n onSelection: (newDate: Date) => void | boolean | Promise;\n };\n };\n Blocks: {\n default: [DatePickerDialog];\n };\n}\n\nconst DateTimePickerModal = templateOnlyComponent();\nexport default DateTimePickerModal;\n\ndeclare module '@glint/environment-ember-loose/registry' {\n export default interface Registry {\n DateTimePickerModal: typeof DateTimePickerModal;\n }\n}\n","import { tracked } from '@glimmer/tracking';\nimport EmberObject, { set, computed, setProperties } from '@ember/object';\nimport { gt } from '@ember/object/computed';\nimport { getCameraItemByGlobalDeviceId } from 'customer-site/components/video/video-streaming/video-streaming-features/camera-items';\nimport { Continuous, Motion } from 'customer-site/enums/RecordingIntervalType';\nimport { NoError, NoPermissions } from 'customer-site/enums/VideoSourceError';\nimport { getSVRMotionIntervals } from 'customer-site/models/video/devices/camera';\nimport { isEmptyObject } from 'customer-site/utils/general';\nimport { sentryWithScopeAndError } from '@adc/app-infrastructure/utils/sentry';\nimport addSeconds from 'date-fns/addSeconds';\nimport isAfter from 'date-fns/isAfter';\nimport isBefore from 'date-fns/isBefore';\nimport subSeconds from 'date-fns/subSeconds';\n\nimport type {\n AllStreamsIntervalsIndividual,\n IntervalData\n} from 'customer-site/components/video/video-player/playback-features/types';\nimport type { StreamUsage } from 'customer-site/enums/StreamUsage';\nimport type Interval from 'customer-site/models/video/interval';\nimport type IntervalsGroup from 'customer-site/models/video/intervals-group';\nimport type SdCardVideoSource from 'customer-site/models/video/video-sources/sd-card-video-source';\nimport type SvrVideoSource from 'customer-site/models/video/video-sources/svr-video-source';\nimport type AjaxService from 'customer-site/services/ajax';\nimport type PlaybackInfoCacheManager from 'customer-site/services/video/playback-info-cache-manager';\nimport type { AVSDataObject } from '../../advanced-video-search/page/index';\nimport type { CachedCameraItemParameters, CameraItem } from '../../video-streaming/video-streaming-features/types';\nimport type { AllStreamsIntervals, IntervalInfoAtTime, IntervalsData, StreamsInfoAtTime } from './types';\n\n/**\n * Intended to be used as the forceLoadFreshIntervals argument into resetIntervals().\n * IntervalSetting.Normal: Uses cache if we're in single stream mode and initialStreamDataLoaded.\n * IntervalSetting.HardReset: Will not use cache.\n */\nexport enum IntervalSetting {\n Normal,\n HardReset\n}\n\nexport enum NextAvailableTimeAction {\n ResetIntervalsAndResume,\n DisconnectPlaybackEnded,\n DisconnectNoPlayback,\n HandleNewTime,\n UpdateCurrentTime\n}\n\n/**\n * Earliest/Latest records and the intervals for all devices. Often retrieved toether, combined to lower complexity of various methods\n */\nexport type IntervalsControlData = {\n earliestRecord: Date | null;\n latestRecord: Date | null;\n allStreamsIntervals: IntervalsData[] | null;\n};\n\nexport type GetVideoSourceMethod = (\n deviceId: string,\n shouldReload: boolean\n) => Promise;\n\n/**\n * The IntervalsControlData as well as the interval info for the current time and where the next available video is.\n * Often retrieved toether, combined to lower complexity of various methods\n */\nexport interface IntervalsControlDataForTime {\n intervalsControlData: IntervalsControlData;\n nextVideoAvailableAt: Date | null;\n intervalInfoAtTime: IntervalInfoAtTime;\n}\n\n/**\n * Retrieves the date value for a string or null.\n */\nconst FnRecordToDate = (record: string) => (record && new Date(record)) || null;\n\n/**\n * 120,000 = 2 minutes = The minimum time in milliseconds before we should\n * hard reset the cache the next time the user navigates to that camera in the dropdown.\n * If it has been shorter than this time, then we can continue using the cached intervals.\n * If it has been longer than this time, then intervals will be null, and we should do a hard reset and reload the intervals.\n */\nexport const CoverageCacheTimeMilliseconds = 120000;\n\n/**\n * Class for efficient management of recording interval data.\n */\nexport default class IntervalsControl extends EmberObject {\n constructor(playbackInfoCacheManager: PlaybackInfoCacheManager) {\n super();\n this._playbackInfoCacheManager = playbackInfoCacheManager;\n }\n\n /**\n * The intervals data for all of the streams retrieved from the backend as an array.\n * These are in the form of a fixed 4-length arrays describing the start, end, interval and type of each interval.\n */\n @tracked\n private _allStreamsIntervals: IntervalsData[] | null = null;\n\n @computed('_allStreamsIntervals')\n get allStreamsIntervals(): IntervalsData[] | null {\n return this._allStreamsIntervals;\n }\n\n /**\n * Similar to allStreamsIntervals, but this is filtered to only include continuous intervals.\n */\n @tracked\n private _allStreamsIntervalsFiltered: IntervalsData[] | null = null;\n\n /**\n * When is the start of the earliest video playback for login-as-login?\n * This is null for the customer and for login-as-login without permissions.\n */\n @tracked\n private _earliestPlaybackTimeUtc: Date | null = null;\n\n @computed('_earliestPlaybackTimeUtc')\n get earliestPlaybackTimeUtc(): Date | null {\n return this._earliestPlaybackTimeUtc;\n }\n\n /**\n * The date of the earliest recording interval.\n */\n @tracked\n private _earliestRecord: Date | null = null;\n\n @computed('_earliestRecord')\n get earliestRecord(): Date | null {\n return this._earliestRecord;\n }\n\n /**\n * The date of the latest recording interval.\n */\n @tracked\n private _latestRecord: Date | null = null;\n\n @computed('_latestRecord')\n get latestRecord(): Date | null {\n return this._latestRecord;\n }\n\n /**\n * The playback cache manager service (video.playback-info-cache-manager)\n */\n private _playbackInfoCacheManager: PlaybackInfoCacheManager;\n\n /**\n * The enum from base-video-player to represent the type of player (live, continuous cloud, sd card).\n */\n private _playerType: StreamUsage | undefined;\n\n setPlayerType(playerType: StreamUsage | undefined): void {\n this._playerType = playerType;\n }\n\n /**\n * Calculates everything has been loaded, and commands can start to be used.\n * Returns whether the intervals have loaded.\n */\n @gt('allStreamsIntervals.length', 0)\n declare isCoverageLoaded: boolean;\n\n /**\n * Retrieves the earliest and latest record date for all the streams.\n */\n private getEarliestAndLatestRecordDates(allStreamsIntervals: AllStreamsIntervals): {\n earliestRecordDate: Date | null;\n latestRecordDate: Date | null;\n } {\n let allStreamsEarliestRecordDate: Date | null = null,\n allStreamsLatestRecordDate: Date | null = null;\n\n (allStreamsIntervals || []).forEach((stream) => {\n const streamEarliestRecordDate = stream.earliestRecord,\n streamLatestRecordDate = stream.latestRecord;\n\n if (!streamEarliestRecordDate || !streamLatestRecordDate) {\n return;\n }\n\n // If this is the first interval in the array.\n if (!allStreamsEarliestRecordDate || !allStreamsLatestRecordDate) {\n allStreamsEarliestRecordDate = streamEarliestRecordDate;\n allStreamsLatestRecordDate = streamLatestRecordDate;\n } else {\n allStreamsEarliestRecordDate = isAfter(allStreamsEarliestRecordDate, streamEarliestRecordDate)\n ? streamEarliestRecordDate\n : allStreamsEarliestRecordDate;\n\n allStreamsLatestRecordDate = isAfter(streamLatestRecordDate, allStreamsLatestRecordDate)\n ? streamLatestRecordDate\n : allStreamsLatestRecordDate;\n }\n });\n\n return {\n earliestRecordDate: allStreamsEarliestRecordDate,\n latestRecordDate: allStreamsLatestRecordDate\n };\n }\n\n /**\n * Retrieves an array of gap information for the time period selected.\n *\n * @param intervalsFound Array of all intervals retrieved for the device.\n * @param timelineStartTime The start point for the timeline period.\n * @param timelineEndTime The end point for the timeline period.\n * @param earliestRecordDate The earliest that the device has recordings.\n * @param latestRecordDate The latest that the device has recordings.\n */\n private getIntervalDataForTimeWindow(\n intervalsFound: Interval[],\n timelineStartTime: Date,\n timelineEndTime: Date,\n earliestRecordDate?: Date,\n latestRecordDate?: Date\n ): IntervalsData {\n if (!intervalsFound || !earliestRecordDate || !latestRecordDate) {\n intervalsFound = [];\n }\n\n return {\n cameraItem: null,\n earliestRecord: earliestRecordDate || timelineStartTime,\n latestRecord: latestRecordDate || timelineEndTime,\n intervals: intervalsFound.map(({ startTime, endTime, toggledBy, type }) => {\n return {\n toggledBy,\n type,\n startTime: new Date(startTime),\n endTime: new Date(endTime)\n };\n })\n };\n }\n\n /**\n * Gets intervals data from the cameraItems.\n */\n async getIntervals(\n cameraItems: CameraItem[],\n forceLoadFreshIntervals: boolean,\n getVideoSource: GetVideoSourceMethod\n ): Promise {\n const allIntervals: AllStreamsIntervals = [];\n\n // Update all player objects with new URLs, and wait for all to finish.\n await Promise.all(\n cameraItems.map(async (cameraItem) => {\n if (!cameraItem.model) {\n return;\n }\n\n const globalDeviceId = cameraItem.model.id,\n vidSource = await getVideoSource(globalDeviceId, forceLoadFreshIntervals);\n\n if (!vidSource) {\n allIntervals.push({\n globalDeviceId,\n intervalsFound: []\n });\n return;\n }\n\n const intervals = await this.getIntervalsFromSource(globalDeviceId, vidSource);\n allIntervals.push(intervals);\n })\n );\n\n return allIntervals;\n }\n\n /**\n * Retrieves an allStreamsIntervals array containing intervals information separated by stream.\n */\n private getStreamIntervalsArrayForTimeWindow(\n intervals: AllStreamsIntervals,\n timelineStartTime: Date,\n timelineEndTime: Date,\n cameraItems: CameraItem[]\n ): IntervalsData[] {\n const allStreamsIntervals: IntervalsData[] = [];\n\n (intervals || []).forEach((stream) => {\n const { earliestRecord, latestRecord, intervalsFound, activelyRecording } = stream,\n streamEarliestRecordDate = earliestRecord,\n streamLatestRecordDate = latestRecord;\n\n const intervalsData = this.getIntervalDataForTimeWindow(\n intervalsFound,\n timelineStartTime,\n timelineEndTime,\n streamEarliestRecordDate,\n streamLatestRecordDate\n );\n intervalsData.cameraItem = getCameraItemByGlobalDeviceId(stream.globalDeviceId, cameraItems);\n intervalsData.activelyRecording = activelyRecording;\n allStreamsIntervals.push(intervalsData);\n });\n\n return allStreamsIntervals;\n }\n\n /**\n * Set schedule paused status for each stream.\n */\n private getStreamPausedStatus(getVideoSource: GetVideoSourceMethod): void {\n this._allStreamsIntervals?.map(async (stream, index) => {\n const cameraModel = await stream.cameraItem?.model;\n\n if (!cameraModel) {\n return;\n }\n\n const videoSource = await getVideoSource(cameraModel.id, false),\n recordingSchedule = await videoSource?.recordingSchedule,\n isPaused = recordingSchedule?.isPaused ?? false;\n\n if (!this._allStreamsIntervals?.[index]) {\n return;\n }\n\n set(this._allStreamsIntervals[index], 'isSchedulePaused', isPaused);\n });\n }\n\n /**\n * Converts an intervals object into an allStreamsIntervals array of objects of size one.\n *\n * @param intervals an object with interval information for a stream\n * @param globalDeviceId\n * @param errorEnum the errorEnum associated with the video source, if any\n */\n private intervalsToAllStreamsIntervals(\n intervals: IntervalsGroup | null,\n globalDeviceId: string,\n errorEnum?: number\n ): AllStreamsIntervals | null {\n if (!intervals) {\n return null;\n }\n\n const { intervalsFound, earliestRecord, latestRecord } = intervals.getProperties(\n 'intervalsFound',\n 'earliestRecord',\n 'latestRecord'\n );\n\n if (!intervalsFound) {\n return null;\n }\n\n return [\n {\n intervalsFound: intervalsFound.toArray(),\n earliestRecord,\n latestRecord,\n globalDeviceId,\n errorEnum\n }\n ];\n }\n\n /**\n * Determines the next available piece of video after the startTime param for the given stream.\n *\n * @param intervalData\n * @param startTime The time where we want to begin looking for video.\n *\n * @returns The time closest to the startTime where video is available.\n */\n private nextVideoAvailableForStream(intervalData: IntervalsData | null, startTime: Date): Date | null {\n let nextVideoAvailableAt = null;\n\n if (!intervalData) {\n return nextVideoAvailableAt;\n }\n\n const interval = intervalData.intervals?.find(({ endTime: intervalEnd }) => isAfter(intervalEnd, startTime));\n\n if (interval) {\n const { startTime: intervalStart } = interval;\n\n // if startTime is inside of an interval, video is available immediately.\n if (intervalStart.getTime() <= startTime.getTime()) {\n nextVideoAvailableAt = startTime;\n } else {\n nextVideoAvailableAt = intervalStart;\n }\n }\n\n return nextVideoAvailableAt;\n }\n\n /**\n * Sets the intervals for this object to use.\n *\n * @param allStreamsIntervals The intervals information for all the streams on the page.\n */\n private setAllStreamsIntervalsFiltered(allStreamsIntervals: IntervalsData[]): void {\n // Were no intervals passed?\n if (!allStreamsIntervals.length || !allStreamsIntervals[0].intervals) {\n return;\n }\n\n const newAllStreamsIntervals = allStreamsIntervals.map((intervalsData) => ({\n ...intervalsData,\n intervals: intervalsData.intervals?.filter(({ type }) => type === Continuous)\n }));\n\n this._allStreamsIntervalsFiltered = newAllStreamsIntervals;\n }\n\n /**\n * Based on what the next available start time is, this returns the appropriate playback action to take.\n */\n determineNextAvailableTimeAction(\n time: Date,\n isAvsContext: boolean,\n initStarted: boolean,\n seekTypeEnum: number | null\n ): { nextAvailableTimeAction: NextAvailableTimeAction; nextVideoAvailableAt?: Date } {\n const { intervalsControlData, nextVideoAvailableAt, intervalInfoAtTime } = this.getDataForTime(time);\n\n // If there is no next available start time, go into Disconnected state for all connected cameras.\n // This is most likely due to null/empty intervals.\n if (!nextVideoAvailableAt) {\n const anyDeviceWithContinuousIntervalActivelyRecording = intervalsControlData.allStreamsIntervals?.some(\n (intervalData) =>\n intervalData.activelyRecording &&\n intervalData.intervals?.any((interval) => interval.type === Continuous)\n );\n\n // If there are any devices that are actively recording, we can reload interval data and continue where we left off.\n // If we are in an AVS context, lets skip doing this, as the intervals on the page represent found results, and wont change if they are reset\n if (anyDeviceWithContinuousIntervalActivelyRecording && !isAvsContext) {\n return { nextAvailableTimeAction: NextAvailableTimeAction.ResetIntervalsAndResume };\n }\n\n return { nextAvailableTimeAction: NextAvailableTimeAction.DisconnectPlaybackEnded };\n }\n\n // If we're in a gap, update the current time to the next available start time and seek if initStarted.\n if (intervalInfoAtTime?.isInGap && initStarted && seekTypeEnum) {\n // If the most recent seek type is not null,\n // meaning the user interacted with the timeline,\n // then stop playback to prevent the timeline from jumping forward.\n // It is reset to null whenever the video begins playing.\n return { nextAvailableTimeAction: NextAvailableTimeAction.DisconnectNoPlayback };\n }\n\n if (intervalInfoAtTime?.isInGap && initStarted) {\n return { nextAvailableTimeAction: NextAvailableTimeAction.HandleNewTime, nextVideoAvailableAt };\n }\n\n // Otherwise, just update the current time. Seeking is not necessary.\n return { nextAvailableTimeAction: NextAvailableTimeAction.UpdateCurrentTime, nextVideoAvailableAt };\n }\n\n /**\n * Returns earliestRecord, latestRecord, and allStreamsIntervals\n */\n getData(): IntervalsControlData {\n return {\n earliestRecord: this._earliestRecord,\n latestRecord: this._latestRecord,\n allStreamsIntervals: this._allStreamsIntervals\n };\n }\n\n /**\n * Returns earliestRecord, latestRecord, and allStreamsIntervals as well as interval data for current time and next available time\n */\n getDataForTime(time: Date): IntervalsControlDataForTime {\n return {\n intervalsControlData: this.getData(),\n nextVideoAvailableAt: this.nextVideoAvailableAt(time),\n intervalInfoAtTime: this.getIntervalInfoForCurrentTime(time)\n };\n }\n\n /**\n * Returns the first time we have video available.\n * This is necessary because earliest record is not guaranteed to be the earliest available video time for login as login.\n * Also stores the value (if one exists) to this.earliestPlaybackTimeUtc\n *\n * @returns The earliest time we have video available.\n */\n getAndStoreEarliestAvailablePlaybackTime(): Date | undefined {\n const { _allStreamsIntervalsFiltered } = this;\n\n // Extract the start time from the first interval of each stream and find the earliest one.\n const earliestPlaybackTimeUtc = _allStreamsIntervalsFiltered\n ?.map(({ intervals }) => {\n const firstInterval = intervals?.[0];\n return firstInterval?.startTime;\n })\n .reduce((earliestDate, currentDate) => {\n if (currentDate && earliestDate && isBefore(currentDate, earliestDate)) {\n return currentDate;\n }\n\n return earliestDate;\n });\n\n if (earliestPlaybackTimeUtc) {\n this._earliestPlaybackTimeUtc = earliestPlaybackTimeUtc;\n }\n\n return earliestPlaybackTimeUtc;\n }\n\n /**\n * * Gets interval information for all the streams for the current time.\n *\n * @param currentTime The time to check.\n */\n getIntervalInfoForCurrentTime(currentTime: Date): IntervalInfoAtTime {\n const { _allStreamsIntervalsFiltered } = this;\n\n const streamsInfo: StreamsInfoAtTime = [];\n let streamsInGapCount = 0;\n let nextVideoTime: Date | null = null;\n\n _allStreamsIntervalsFiltered?.forEach((intervalsData) => {\n const streamNextVideoTime = this.nextVideoAvailableForStream(intervalsData, currentTime);\n let isInGap = false;\n // cameraItem will be null when useVideoStreamingGroups is false as it is unneeded.\n const globalDeviceId = intervalsData.cameraItem?.model ? intervalsData.cameraItem.model.id : null;\n\n if (!streamNextVideoTime || isAfter(streamNextVideoTime, currentTime)) {\n isInGap = true;\n streamsInGapCount++;\n }\n\n if (streamNextVideoTime) {\n if (!nextVideoTime || isBefore(streamNextVideoTime, nextVideoTime)) {\n nextVideoTime = streamNextVideoTime;\n }\n }\n\n streamsInfo.push({\n isInGap,\n globalDeviceId\n });\n });\n\n return {\n isInGap: !nextVideoTime || streamsInGapCount === _allStreamsIntervalsFiltered?.length,\n nextVideoTime,\n streamsInfo,\n streamsInGapCount\n };\n }\n\n /**\n * Retrieved allStreamsIntervals from cache if appropriate for the scenario\n */\n getIntervalsFromCacheIfNeeded(\n resetIntervalsSetting: number,\n deviceIds: string[],\n initialStreamDataLoaded: boolean\n ): { allStreamsIntervals: AllStreamsIntervals; forceLoadFreshIntervals: boolean } | void {\n const { _playerType, _playbackInfoCacheManager } = this;\n const allStreamsIntervals: AllStreamsIntervals = [];\n let forceLoadFreshIntervals = false;\n\n if (!_playerType) {\n return;\n }\n\n switch (resetIntervalsSetting) {\n case IntervalSetting.Normal:\n forceLoadFreshIntervals = !initialStreamDataLoaded;\n break;\n case IntervalSetting.HardReset:\n forceLoadFreshIntervals = true;\n break;\n }\n\n if (!forceLoadFreshIntervals) {\n deviceIds.forEach((id) => {\n const videoSource = _playbackInfoCacheManager.getVideoSourceFromCache(id, _playerType);\n if (!videoSource) {\n forceLoadFreshIntervals = true;\n return;\n }\n\n const intervals = _playbackInfoCacheManager.getIntervalsFromCache(\n id,\n _playerType,\n CoverageCacheTimeMilliseconds\n );\n if (!intervals) {\n forceLoadFreshIntervals = true;\n return;\n }\n\n const allStreamsIntervalsIndividual = this.intervalsToAllStreamsIntervals(\n intervals,\n id,\n videoSource.errorEnum\n );\n if (!allStreamsIntervalsIndividual?.length) {\n forceLoadFreshIntervals = true;\n return;\n }\n\n allStreamsIntervals.push(...allStreamsIntervalsIndividual);\n });\n }\n\n return {\n allStreamsIntervals,\n forceLoadFreshIntervals\n };\n }\n\n /**\n * Gets intervals data from the videoSource passed in, also appends the errorEnum from the video source to the intervals data.\n *\n * @param globalDeviceId The global device id on the camera model.\n * @param videoSource Object that contains video source. This includes camera or player objects.\n */\n private async getIntervalsFromSource(\n globalDeviceId: string,\n videoSource: SdCardVideoSource | SvrVideoSource | null\n ): Promise {\n const { _playerType, _playbackInfoCacheManager } = this;\n const intervalsData: Partial = {\n globalDeviceId\n };\n\n if (!videoSource || !_playerType) {\n return intervalsData as AllStreamsIntervalsIndividual;\n }\n\n intervalsData.errorEnum = videoSource.errorEnum;\n\n _playbackInfoCacheManager.addVideoSourceToCache(globalDeviceId, _playerType, videoSource);\n\n const intervals = await videoSource.intervals;\n\n if (!intervals) {\n return intervalsData as AllStreamsIntervalsIndividual;\n }\n\n _playbackInfoCacheManager.addIntervalsToCache(globalDeviceId, _playerType, intervals);\n\n const { earliestRecord, latestRecord, intervalsFound, activelyRecording } = intervals;\n\n setProperties(intervalsData, {\n earliestRecord,\n latestRecord,\n intervalsFound: intervalsFound.toArray(),\n activelyRecording\n });\n\n return intervalsData as AllStreamsIntervalsIndividual;\n }\n\n /**\n * Retrieves data about the intervals passed in and updates the associated interval data to reflect.\n */\n getIntervalUsabilityAndUpdateValues(\n allStreamsIntervals: AllStreamsIntervals,\n cameraItems: CameraItem[],\n timelineStartTime: Date,\n timelineEndTime: Date,\n getVideoSource: GetVideoSourceMethod,\n avsDataObject?: AVSDataObject\n ): {\n foundPlayerWithoutErrors: boolean;\n errorEnumMapping: Record;\n earliestRecordDate: Date | null;\n latestRecordDate: Date | null;\n } {\n let foundUsableIntervalData = false,\n foundPlayerWithoutErrors = false;\n const errorEnumMapping: Record = {};\n\n allStreamsIntervals.forEach((intervalsData) => {\n const errorEnum = intervalsData?.errorEnum ?? NoError;\n\n if (\n !intervalsData ||\n !intervalsData.intervalsFound ||\n !intervalsData.intervalsFound.length ||\n avsDataObject?.searchFailed\n ) {\n errorEnumMapping[intervalsData.globalDeviceId] = errorEnum;\n return;\n }\n\n // This will only happen for login as login where we have intervals from the checks above.\n // However, we have no video playback available because of no continuous intervals,\n // so we error out with a no permission error.\n // We do not return early because we still have intervals that we want to set.\n if (!intervalsData.intervalsFound.any((interval) => interval.get('type') === Continuous)) {\n errorEnumMapping[intervalsData.globalDeviceId] = NoPermissions;\n }\n\n foundUsableIntervalData = true;\n\n // It is possible for interval data to be usable but for a player to still have errors\n // (e.g. we're doing a login-as without video permissions).\n if (errorEnum === NoError) {\n foundPlayerWithoutErrors = true;\n } else {\n errorEnumMapping[intervalsData.globalDeviceId] = errorEnum;\n }\n });\n\n if (!foundUsableIntervalData) {\n this._allStreamsIntervals = null;\n return {\n errorEnumMapping,\n foundPlayerWithoutErrors,\n earliestRecordDate: null,\n latestRecordDate: null\n };\n }\n\n const { earliestRecordDate, latestRecordDate } = this.getEarliestAndLatestRecordDates(allStreamsIntervals),\n allStreamsIntervalsForWindow = this.getStreamIntervalsArrayForTimeWindow(\n allStreamsIntervals,\n timelineStartTime,\n timelineEndTime,\n cameraItems\n );\n\n this._allStreamsIntervals = allStreamsIntervalsForWindow;\n this._earliestRecord = earliestRecordDate;\n this._latestRecord = latestRecordDate;\n\n this.getStreamPausedStatus(getVideoSource);\n this.setAllStreamsIntervalsFiltered(allStreamsIntervalsForWindow);\n\n return {\n foundPlayerWithoutErrors,\n errorEnumMapping,\n earliestRecordDate,\n latestRecordDate\n };\n }\n\n /**\n * Retrieves the times that should be reflected from a reset\n */\n getResetTimeValues(timeInterval: number | null): {\n timelineStartTime: Date;\n timelineEndTime: Date;\n newCurrentTime: Date;\n } | void {\n const now = new Date(),\n { _earliestPlaybackTimeUtc } = this || {};\n\n if (!timeInterval) {\n return;\n }\n\n const earlyPlaybackStart =\n _earliestPlaybackTimeUtc && isBefore(_earliestPlaybackTimeUtc, subSeconds(now, timeInterval - 1));\n let timelineStartTime: Date, timelineEndTime: Date, newCurrentTime: Date;\n\n // When the alarm starts outside our interval, we start at the last alarm's start, and we end one interval after.\n // Otherwise, we default to starting one interval ago and ending now.\n // There should be a total of timeInterval seconds between (and including) timelineStartTime and timelineEndTime,\n // so 1 needs to be subtracted.\n if (earlyPlaybackStart) {\n timelineStartTime = _earliestPlaybackTimeUtc;\n timelineEndTime = addSeconds(_earliestPlaybackTimeUtc, timeInterval - 1);\n newCurrentTime = _earliestPlaybackTimeUtc;\n } else {\n timelineStartTime = subSeconds(now, timeInterval - 1);\n timelineEndTime = now;\n newCurrentTime = subSeconds(now, timeInterval / 2);\n }\n\n return {\n timelineStartTime,\n timelineEndTime,\n newCurrentTime\n };\n }\n\n /**\n * Checks that intervals data deviceId's match the deviceId's for the cameras displaying on the screen.\n */\n intervalsDataMatchesDisplayedCams(\n allStreamsIntervals: AllStreamsIntervals,\n cachedCameraItemParameters: CachedCameraItemParameters | null\n ): boolean {\n if (\n !allStreamsIntervals ||\n isEmptyObject(allStreamsIntervals) ||\n !cachedCameraItemParameters ||\n !cachedCameraItemParameters.displayedDeviceIds\n ) {\n // Returning true since this method just returns false if we have data, but it's for a different camera.\n return true;\n }\n\n const { displayedDeviceIds } = cachedCameraItemParameters;\n\n return displayedDeviceIds.every((deviceId) => {\n return allStreamsIntervals.some((stream) => {\n return !isEmptyObject(stream) && stream.globalDeviceId === deviceId;\n });\n });\n }\n\n /**\n * Loads motion intervals for SVR devices and updates this._allStreamsIntervals with the result\n */\n async loadSvrMotionIntervals(\n ajax: AjaxService,\n timelineStartTime: Date | null,\n timelineEndTime: Date | null\n ): Promise {\n const { _allStreamsIntervals } = this;\n\n if (!_allStreamsIntervals) {\n sentryWithScopeAndError('cant load motion intervals without allStreamsIntervals data');\n return;\n }\n\n const newIntervalMap = new Map();\n\n await Promise.all(\n _allStreamsIntervals.map(async (intervalsData) => {\n const { cameraItem, intervals } = intervalsData,\n videoSource = await cameraItem?.model?.svrVideoSource,\n svr = await videoSource?.get('svr'),\n deviceId = cameraItem?.player?.deviceId;\n\n if (!svr || !svr.supportsMotionIntervals || !deviceId || !timelineStartTime || !timelineEndTime) {\n return;\n }\n\n const motionIntervals = await getSVRMotionIntervals(ajax, deviceId, timelineStartTime, timelineEndTime);\n\n if (!motionIntervals) {\n sentryWithScopeAndError('could not retrieve motion intervals for device', { deviceId });\n return;\n }\n\n // Removing the motion intervals which were loaded already in the video source before we add the new ones\n const newIntervals = intervals?.filter((interval) => interval.type !== Motion) || [];\n\n motionIntervals.data.forEach((motionInterval) => {\n const { attributes } = motionInterval;\n\n const newMotionInterval: IntervalData = {\n toggledBy: attributes.toggledBy,\n type: attributes.type,\n startTime: FnRecordToDate(attributes.startTime) as Date,\n endTime: FnRecordToDate(attributes.endTime) as Date\n };\n\n newIntervals.push(newMotionInterval);\n });\n\n newIntervalMap.set(deviceId, newIntervals);\n })\n );\n\n const newAllStreamsIntervals = [];\n\n for (let i = 0; i < _allStreamsIntervals.length; i++) {\n const intervalsData = _allStreamsIntervals[i],\n deviceId = intervalsData.cameraItem?.player?.deviceId,\n intervalsForDevice = newIntervalMap.get(deviceId) || intervalsData.intervals;\n\n newAllStreamsIntervals[i] = {\n ...intervalsData,\n intervals: intervalsForDevice\n };\n }\n\n this._allStreamsIntervals = newAllStreamsIntervals;\n }\n\n /**\n * Determines the next available piece of video after the startTime param.\n *\n * @param startTime The time where we want to begin looking for video.\n *\n * @returns The time closest to the startTime where video is available.\n */\n nextVideoAvailableAt(startTime: Date): Date | null {\n const { _allStreamsIntervalsFiltered } = this;\n let nextVideoAvailableAt: Date | null = null;\n\n if (!_allStreamsIntervalsFiltered?.length) {\n return null;\n }\n\n for (let i = 0; i < _allStreamsIntervalsFiltered?.length; i++) {\n const intervalData = _allStreamsIntervalsFiltered[i],\n nextVideoForStream = this.nextVideoAvailableForStream(intervalData, startTime);\n\n if (nextVideoForStream === startTime) {\n return startTime;\n }\n\n if (!nextVideoAvailableAt || (nextVideoForStream && isBefore(nextVideoForStream, nextVideoAvailableAt))) {\n nextVideoAvailableAt = nextVideoForStream;\n }\n }\n\n return nextVideoAvailableAt;\n }\n\n /**\n * Sets earliestRecord and latestRecord values\n */\n setEarliestAndLatestRecords(earliestRecord: Date, latestRecord: Date): void {\n this._earliestRecord = earliestRecord;\n this._latestRecord = latestRecord;\n }\n}\n","import type { CameraItem } from '../../video-streaming/video-streaming-features/types';\n\n// region exported methods\n\n/**\n * Returns the number of cameras (in cameraItems, ie cameras on screen) in the selected state.\n *\n * @param state the state enum to check for\n */\nexport function getCamerasCountInState(cameraItems: CameraItem[], state: number): number {\n return getCamerasInState(cameraItems, state).length;\n}\n\n/**\n * Returns the array of cameras (in cameraItems, ie cameras on screen) in the selected state.\n *\n * @param state the state enum to check for\n */\nexport function getCamerasInState(cameraItems: CameraItem[], state: number): CameraItem[] {\n if (!cameraItems) {\n return [];\n }\n\n return cameraItems.filter((cameraItem) => cameraItem.model?.playerState === state);\n}\n","import { tracked } from '@glimmer/tracking';\nimport { isDestroyed } from '@adc/ember-utils/utils/ember-helpers';\nimport { computed } from '@ember/object';\nimport { equal } from '@ember/object/computed';\nimport { later, cancel, next } from '@ember/runloop';\nimport {\n ALL_CAMERAS_ID,\n ALL_CONNECTED_CAMERAS_ID,\n getCameraItemByGlobalDeviceId,\n setCameraProperties\n} from 'customer-site/components/video/video-streaming/video-streaming-features/camera-items';\nimport { StreamUsage } from 'customer-site/enums/StreamUsage';\nimport { AutoRetryConnection, Pause, Play, Retry, SpeedDropdown } from 'customer-site/enums/TrackedEvent';\nimport {\n FROZEN_STATE,\n LOADING_STATE,\n PLAYING_STATE,\n DISCONNECTED_STATE,\n READY_STATE,\n INITIALIZING_STATE\n} from 'customer-site/enums/VideoPlayerStateEnum';\nimport { NOT_VISIBLE_STATE } from 'customer-site/enums/VideoPlayerStateEnum';\nimport {\n PlaybackEnded,\n NoPlaybackVideoAvailable,\n NoError,\n PlaybackServerConnectionFailed\n} from 'customer-site/enums/VideoSourceError';\nimport { NUM_MILLISECONDS_IN_SECOND, NUM_SECONDS_IN_DAY, NUM_SECONDS_IN_HOUR } from 'customer-site/utils/datetime';\nimport { convertErrorEnumToString } from 'customer-site/utils/video/general';\nimport { getSpeedDropdownEventEnum } from 'customer-site/utils/video/wavefront-stats';\nimport { POST } from '@adc/ajax/services/adc-ajax';\nimport { sentryWithScopeAndWarn } from '@adc/app-infrastructure/utils/sentry';\nimport { implementsBasePlayer } from '@adc/video-player/classes/state-controllers/base-player';\nimport OespPlaybackStateController from '@adc/video-player/classes/state-controllers/oesp-playback-state-controller';\nimport WebRtcProxyPlaybackStateController from '@adc/video-player/classes/state-controllers/webrtc-proxy-playback-state-controller';\nimport { isAfter, isBefore, startOfDay } from 'date-fns';\nimport { utcToZonedTime, zonedTimeToUtc } from 'date-fns-tz';\nimport addMinutes from 'date-fns/addMinutes';\nimport addSeconds from 'date-fns/addSeconds';\nimport differenceInMilliseconds from 'date-fns/differenceInMilliseconds';\nimport differenceInSeconds from 'date-fns/differenceInSeconds';\nimport subSeconds from 'date-fns/subSeconds';\nimport PlayersControl from '../../utils/players-control';\nimport { getCamerasCountInState } from './page-state';\n\nimport type EnvSettingsService from '@adc/app-infrastructure/services/env-settings';\nimport type BaseStateController from '@adc/video-player/classes/state-controllers/base-state-controller';\nimport type { EmberRunTimer } from '@ember/runloop/types';\nimport type Camera from 'customer-site/models/video/devices/camera';\nimport type AjaxService from 'customer-site/services/ajax';\nimport type Stats from 'customer-site/services/stats';\nimport type PlaybackInfoCacheManager from 'customer-site/services/video/playback-info-cache-manager';\nimport type { CameraItem, PlayerInfo } from '../../video-streaming/video-streaming-features/types';\nimport type { GetVideoSourceMethod, IntervalsControlData, IntervalsControlDataForTime } from './intervals-control';\nimport type { CamerasDataObject, StreamsInfoAtTime } from './types';\n\n/**\n * The timeout period (in milliseconds) for deferring subsequent API calls.\n * API calls need to be debounced so that the server is not overloaded with API requests.\n */\nconst DeferTimeoutPeriod = 500;\n\n/**\n * The minimum time in seconds to save the cursor position on the timeline.\n * If the time change is less than this value, it will move to the previous/next timeline window without saving the position.\n * For example, seeking past the end of the timeline will cause the timeline to change\n * and the cursor to appear at the beginning of the timeline.\n */\nconst MinTimeChangeThresholdInSecondsForSavingCursorPosition = 60;\n\n/**\n * Maximum amount of time (in minutes) per backend request.\n */\nexport const PlaybackMaxBlockDuration = 60;\n\ntype SetPlayerUrlsMethod = (\n player: PlayerInfo,\n deviceId: string,\n currentTime: Date,\n videoEndTime: Date\n) => Promise;\n\ntype GetPlaybackStateControllersMethod = () => BaseStateController[] | null;\n\n/**\n * A control for controlling various playback specific functions on playback features\n */\nexport default class PlaybackControl {\n constructor(\n timezone: string,\n envSettings: EnvSettingsService,\n playbackInfoCacheManager: PlaybackInfoCacheManager,\n setPlayerUrls: SetPlayerUrlsMethod,\n moveToNextAvailableStartTime: (fromTime: Date | null) => boolean,\n stats: Stats,\n ajax: AjaxService,\n getPlaybackStateControllers: () => BaseStateController[] | null\n ) {\n this._timezone = timezone;\n this._isTestEnvironment = envSettings.isTestEnvironment();\n this._setPlayerUrls = setPlayerUrls;\n this._moveToNextAvailableStartTime = moveToNextAvailableStartTime;\n this._stats = stats;\n this._ajax = ajax;\n this._playbackInfoCacheManager = playbackInfoCacheManager;\n this._getPlaybackStateControllers = getPlaybackStateControllers;\n this._playersControl = new PlayersControl();\n }\n\n /**\n * The ajax service\n */\n private _ajax: AjaxService;\n\n /**\n * Should we autoplay when playback is capable of being started?\n * (This is used for things such as triggering playback to auto-start when changing pages while playback was already running on sd/svr)\n */\n private _autoPlayWhenReady = false;\n\n setAutoPlayWhenReady(): void {\n this._autoPlayWhenReady = this._isPlaying;\n }\n\n /**\n * The current time internally in the component.\n * Do not modify this value directly. Let the helpers do it for you in order to not risk going out of the range of the timeline.\n * This is not what is displayed on the timeline component itself, although it'll often match that value.\n */\n @tracked\n private _currentTime: Date | null = null;\n\n @computed('_currentTime')\n get currentTime(): Date | null {\n return this._currentTime;\n }\n\n /**\n * Retrieves playbackStateControllers from playback features\n */\n private _getPlaybackStateControllers: GetPlaybackStateControllersMethod;\n\n /**\n * Whether the user has seeked after the stream is paused.\n * This is used as an optimization for trying to seek after a pause without having to restart the stream.\n * This is also used to control the scrubber jitter when seeking during a pause and resuming.\n */\n @tracked\n private _hasSeekedAfterPause = false;\n\n @computed('_hasSeekedAfterPause')\n get hasSeekedAfterPause(): boolean {\n return this._hasSeekedAfterPause;\n }\n\n /**\n * Whether the user has changed the speed after the stream is paused.\n * This is used as an optimization to try to queue a seek command after the stream is resumed rather than restarting the stream.\n */\n @tracked\n private _hasSetSpeedAfterPause = false;\n\n /**\n * Initial seek (in seconds) that must be done when playback starts.\n * This is needed for better seeking experience given the full hour timeline bar.\n */\n private _initialSeekForPlaySeconds = 0;\n\n @computed('_initialSeekForPlaySeconds')\n get initialSeekForPlaySeconds(): number {\n return this._initialSeekForPlaySeconds;\n }\n\n /**\n * Has initialization started? If this is true, then we can freely send any commands to the player.\n */\n @tracked\n private _initStarted = false;\n\n @computed('_initStarted')\n get initStarted(): boolean {\n return this._initStarted;\n }\n\n /**\n * Is the player currently paused?\n */\n @tracked\n private _isPaused = false;\n\n /**\n * Is the actual video playing right now? This should only be set by the events from the video player.\n * This should not be modified by anything besides player events except under very specific circumstances.\n */\n @tracked\n private _isPlaying = false;\n\n /**\n * If the environment is a test environment.\n */\n private _isTestEnvironment: boolean;\n\n /**\n * Is the timeline button currently displaying the play icon on the page?\n * If it is, that means the user has the video paused in the UI.\n */\n @tracked\n private _isTimelineButtonDisplayingPlayIcon = true;\n\n @computed('_isTimelineButtonDisplayingPlayIcon')\n get isTimelineButtonDisplayingPlayIcon(): boolean {\n return this._isTimelineButtonDisplayingPlayIcon;\n }\n\n /**\n * The start time value (in milliseconds) when the user initiates playback using one of the seek types.\n */\n @tracked\n private _loadStartTime: number | null = null;\n\n /**\n * Moves to the next available start time\n */\n private _moveToNextAvailableStartTime: (fromTime: Date | null) => boolean;\n\n /**\n * The state of playback on the page.\n */\n @tracked\n private _pageState = INITIALIZING_STATE;\n\n @computed('_pageState')\n get pageState(): number {\n return this._pageState;\n }\n\n /**\n * The playback cache manager service (video.playback-info-cache-manager)\n */\n private _playbackInfoCacheManager: PlaybackInfoCacheManager;\n\n /**\n * Did the playback have to restart?\n * This means that the overlay showed LOADING_STATE and was unable to begin playing just by showing the frozen state.\n * This is true on initial load and when seeking to a large amount of time from the current time.\n */\n @tracked\n private _playbackRestarted = true;\n\n /**\n * The player controls for the video streams on the page.\n */\n private _playersControl: PlayersControl;\n\n /**\n * The enum from base-video-player to represent the type of player (live, continuous cloud, sd card).\n */\n private _playerType: StreamUsage | undefined;\n\n setPlayerType(playerType: StreamUsage | undefined): void {\n this._playerType = playerType;\n }\n\n /**\n * Contains the seek command to perform next.\n * Null if there is no seek in the queue.\n */\n @tracked\n private _seekInterval: EmberRunTimer | null = null;\n\n /**\n * How did the stream begin playing?\n * This number corresponds to the Tracked Event Enum that triggered playback\n */\n @tracked\n private _seekTypeEnum: number | null = null;\n\n @computed('_seekTypeEnum')\n get seekTypeEnum(): number | null {\n return this._seekTypeEnum;\n }\n\n /**\n * Set player URLs (playback URL, delete URL, etc.).\n */\n private _setPlayerUrls: SetPlayerUrlsMethod;\n\n /**\n * Sets the seek type enum value\n */\n setSeekTypeEnum(seekTypeEnum: number): void {\n this._seekTypeEnum = seekTypeEnum;\n }\n\n /**\n * The speed of playback.\n */\n @tracked\n private _speed = 0;\n\n @computed('_speed')\n get speed(): number {\n return this._speed;\n }\n\n /**\n * The current speed index of availableSpeeds.\n */\n @tracked\n private _speedIndex = 0;\n\n @computed('_speedIndex')\n get speedIndex(): number {\n return this._speedIndex;\n }\n\n /**\n * Stats service\n */\n private _stats: Stats;\n\n /**\n * The amount of streams that are in a gap at the current time.\n */\n @tracked\n private _streamsInGapCount = 0;\n\n /**\n * The task to increment the timer to move the current time forward.\n */\n @tracked\n private _tickInterval: EmberRunTimer | null = null;\n\n /**\n * The timezone of the user.\n */\n private _timezone: string;\n\n /**\n * How many seconds are we displaying on the timeline. (this is usually NUM_SECONDS_IN_HOUR or NUM_SECONDS_IN_DAY)\n */\n @tracked\n private _timeInterval = NUM_SECONDS_IN_HOUR;\n\n @computed('_timeInterval')\n get timeInterval(): number {\n return this._timeInterval;\n }\n\n /**\n * Sets the time interval value\n */\n setTimeInterval(timeInterval: number): void {\n this._timeInterval = timeInterval;\n }\n\n /**\n * The start time of the timeline itself. This will be the start hour or day interval.\n */\n @tracked\n private _timelineStartTime: Date | null = null;\n\n @computed('_timelineStartTime')\n get timelineStartTime(): Date | null {\n return this._timelineStartTime;\n }\n\n /**\n * The end time of the timeline itself. This will be the end hour or day interval.\n */\n @tracked\n private _timelineEndTime: Date | null = null;\n\n @computed('_timelineEndTime')\n get timelineEndTime(): Date | null {\n return this._timelineEndTime;\n }\n\n /**\n * Will disable speed selection while player is loading. This is to avoid command spam.\n */\n @equal('pageState', LOADING_STATE)\n declare disableSpeedSelection: boolean;\n\n /**\n * The time the scrubber bar should be one.\n * This will be the current time (internally according to the component) plus the initial seek in seconds.\n */\n @computed('currentTime', 'initialSeekForPlaySeconds', 'isPlaying')\n get scrubberTime(): Date | undefined {\n const { _initialSeekForPlaySeconds, _isPlaying, _currentTime } = this;\n\n if (!_currentTime) {\n return;\n }\n\n // If we're not playing or if there is no initial seek, then just use the current time.\n if (!_isPlaying || _initialSeekForPlaySeconds === 0) {\n return _currentTime;\n }\n\n // Else if we're playing and have an initial seek, then calculate the scrubber time.\n return addSeconds(_currentTime, _initialSeekForPlaySeconds);\n }\n\n /**\n * If we are using HOUR mode, ie the timeline is showing an hour of data\n */\n @computed('_timeInterval')\n get usingHourMode(): boolean {\n return this._timeInterval === NUM_SECONDS_IN_HOUR;\n }\n\n /**\n * Are all the cameras currently displaying on the page disconnected?\n *\n * @returns True if all cameras on page are in disconnected state.\n */\n private allCamerasDisconnected(cameraItems: CameraItem[]): boolean {\n if (!cameraItems) {\n return true;\n }\n\n return cameraItems.length - getCamerasCountInState(cameraItems, DISCONNECTED_STATE) <= 0;\n }\n\n /**\n * Given an list of states, determine what the page state should be.\n *\n * @param states The current state of each camera on the page.\n */\n private calculatePageState(states: Array): number {\n // The priority of each of these states. eg. If two or more devices are in different states on the page,\n // which state should take precedence.\n const statePriority = [\n PLAYING_STATE,\n INITIALIZING_STATE,\n READY_STATE,\n FROZEN_STATE,\n LOADING_STATE,\n DISCONNECTED_STATE,\n NOT_VISIBLE_STATE\n ];\n\n return statePriority.find((priority) => states.some((state) => state === priority)) ?? READY_STATE;\n }\n\n /**\n * Converts a state enum to a string.\n *\n * @param currentStateEnum The enum to convert to a string (e.g. 0, 1, 2, 3, 4, or 5).\n *\n * @returns The string version of the enum (e.g. playing, initializing, loading, frozen, disconnected, or ready).\n */\n private convertCurrentStateEnumToString(currentStateEnum: number): string | null {\n switch (currentStateEnum) {\n case PLAYING_STATE:\n return 'Playing';\n case INITIALIZING_STATE:\n return 'Initializing';\n case LOADING_STATE:\n return 'Loading';\n case FROZEN_STATE:\n return 'Frozen';\n case DISCONNECTED_STATE:\n return 'Disconnected';\n case READY_STATE:\n return 'Ready';\n default:\n return null;\n }\n }\n\n /**\n * Deletes the players control commands for the camera specified\n */\n deletePlayersControlCommands(cameraIndex: number): void {\n this._playersControl.deletePlayerCommands(cameraIndex);\n }\n\n /**\n * Sets hasReachedEndOfStream and calls handleDisconnectedPlaybackPlayer for connected cameras.\n */\n disconnectNoPlaybackAvailable(camerasDataObject: CamerasDataObject): void {\n setCameraProperties(camerasDataObject.activeCameras, { hasReachedEndOfStream: true }, ALL_CONNECTED_CAMERAS_ID);\n this.handleDisconnectedPlaybackPlayer(NoPlaybackVideoAvailable, ALL_CONNECTED_CAMERAS_ID, camerasDataObject);\n }\n\n /**\n * Sets hasReachedEndOfStream and calls handleDisconnectedPlaybackPlayer for connected cameras.\n */\n disconnectPlaybackEnded(camerasDataObject: CamerasDataObject): void {\n setCameraProperties(camerasDataObject.activeCameras, { hasReachedEndOfStream: true }, ALL_CONNECTED_CAMERAS_ID);\n this.handleDisconnectedPlaybackPlayer(PlaybackEnded, ALL_CONNECTED_CAMERAS_ID, camerasDataObject);\n }\n\n /**\n * Called when the current time changes. Determines the new timeline start time, if the timeline needs to change, otherwise returns undefined.\n *\n * @param oldCurrentTime The previous current time used for maintaining the cursor position.\n */\n private getTimelineChangeFromCurrentTimeChange(oldCurrentTime: Date | null): Date | undefined {\n const { _currentTime, _timeInterval, _timelineStartTime, _timelineEndTime } = this;\n\n if (!_currentTime || !_timelineStartTime || !_timelineEndTime || !_timeInterval || !oldCurrentTime) {\n return;\n }\n\n const isCurrentTimeOutsideTimelineRange =\n isBefore(_currentTime, _timelineStartTime) || isAfter(_currentTime, _timelineEndTime);\n\n // Is the current time NOT within the current interval\n // or is the timeline start/end times outside the earliest/latest records?\n if (isCurrentTimeOutsideTimelineRange) {\n // By how many seconds is the time changing from the old time to the new time?\n const timeChange = differenceInSeconds(_currentTime, oldCurrentTime),\n // Store the cursor percentage based on the distance from timelineStartTime.\n datePercentage =\n differenceInMilliseconds(oldCurrentTime, _timelineStartTime) /\n differenceInMilliseconds(_timelineEndTime, _timelineStartTime),\n // Should the cursor position be saved and keep its relative position?\n saveCursorPosition =\n !timeChange || Math.abs(timeChange) > MinTimeChangeThresholdInSecondsForSavingCursorPosition,\n // Should the timeline move forward or backward?\n moveTimelineForward = timeChange > 0;\n // Default the new start time to be based on the saved cursor position.\n let newStartTime = subSeconds(_currentTime, Math.round(_timeInterval * datePercentage));\n\n if (!saveCursorPosition) {\n // If the cursor position should not be saved,\n // adjust the start time based on whether the new time is before or after the current timeline range.\n newStartTime = moveTimelineForward\n ? _timelineEndTime\n : subSeconds(_timelineStartTime, _timeInterval - 1);\n }\n\n return newStartTime;\n }\n\n return;\n }\n\n /**\n * Sets the current state to disconnected and an error enum at the same time.\n * Disconnected state should never be set without an error enum.\n *\n * @param streamConnectionErrorEnum The error enum used to determine which error message should be displayed.\n * @param isRetryable Is this type of error likely to be fixed by retrying the connection?\n */\n handleDisconnectedPlaybackPlayer(\n streamConnectionErrorEnum: number,\n globalDeviceId: string,\n camerasDataObject: CamerasDataObject\n ): void {\n const { activeCameras, cameraItems, camerasModel } = camerasDataObject;\n\n if (!streamConnectionErrorEnum) {\n console.error(`Invalid value for streamConnectionErrorEnum=${streamConnectionErrorEnum}.`);\n return;\n }\n\n this.updatePageAndPlayerState(DISCONNECTED_STATE, globalDeviceId, activeCameras, streamConnectionErrorEnum);\n\n // If not all the cameras are disconnected, don't reset stream URLs or playback buttons or players control just yet.\n if (!this.allCamerasDisconnected(cameraItems)) {\n return;\n }\n\n this.resetPlaybackButtons(camerasModel);\n\n return;\n }\n\n /**\n * Handles onPlayStarted().\n */\n handleOnPlayStarted(camerasDataObject: CamerasDataObject, globalDeviceId: string): void {\n const { activeCameras, camerasModel } = camerasDataObject,\n { _loadStartTime, _playbackRestarted, _seekTypeEnum, _speed } = this;\n\n setCameraProperties(\n camerasModel,\n {\n isPlaying: true,\n isPaused: false\n },\n globalDeviceId\n );\n\n this.updatePageAndPlayerState(PLAYING_STATE, globalDeviceId, activeCameras);\n\n // loadStartTime and seekTypeEnum will be null after the first video starts playing (when trying to play > 1)\n // We only set load Start/End times and report for the first video to play\n if (!_loadStartTime || !_seekTypeEnum) {\n return;\n }\n\n // Done loading now ready to show stream to user.\n this._isPlaying = true;\n this._isPaused = false;\n this._isTimelineButtonDisplayingPlayIcon = false;\n\n this.reportPlaybackLoadingTimeToWaveFront(\n _loadStartTime,\n performance.now(),\n _playbackRestarted,\n _seekTypeEnum,\n _speed\n );\n\n this._seekTypeEnum = null;\n this._loadStartTime = null;\n }\n\n /**\n * Sets the page to Ready state and then starts playback if autoPlayWhenRead = true\n */\n handlePlaybackPrepared(\n useHdStream: boolean,\n camerasDataObject: CamerasDataObject,\n intervalsControlDataForCurrentTime: IntervalsControlDataForTime\n ): void {\n const { _autoPlayWhenReady } = this;\n\n // Playback preparation done go to the ready state overlay.\n this.updatePageAndPlayerState(READY_STATE, ALL_CONNECTED_CAMERAS_ID, camerasDataObject.activeCameras);\n\n if (_autoPlayWhenReady) {\n this._autoPlayWhenReady = false;\n this.startVideoPlayback(false, useHdStream, camerasDataObject, intervalsControlDataForCurrentTime);\n }\n }\n\n /**\n * Appropriately queue a speed and/or a seek command if the user requested a speed change and/or a seek during pause.\n *\n * @returns True if we need to handle a seek or speed change after pause.\n */\n private handleSeekOrSpeedChangeAfterPause(): boolean {\n const { _hasSeekedAfterPause, _hasSetSpeedAfterPause, _speed } = this;\n\n if (_hasSetSpeedAfterPause) {\n // Clear cache variable.\n this._hasSetSpeedAfterPause = false;\n\n // Queue speed command.\n this._playersControl.setSpeed(_speed);\n }\n\n if (_hasSeekedAfterPause) {\n // Clear cache variable.\n this._hasSeekedAfterPause = false;\n\n // Queue seek command.\n this._playersControl.seek(this.currentTime);\n }\n\n return _hasSeekedAfterPause || _hasSetSpeedAfterPause;\n }\n\n /**\n * Increments the current time and accommodates for any gaps which occur during playback.\n *\n * @param interval How many seconds is a single update to the time?\n */\n private incrementTimer(\n camerasDataObject: CamerasDataObject,\n interval: number,\n intervalsControlDataForCurrentTime: IntervalsControlDataForTime\n ): void {\n const { intervalInfoAtTime } = intervalsControlDataForCurrentTime,\n { _currentTime } = this,\n { cameraItems, camerasModel } = camerasDataObject;\n\n if (!_currentTime) {\n return;\n }\n\n if (cameraItems.length > 1) {\n const streamsInfo = intervalInfoAtTime.streamsInfo,\n newStreamsInGapCount = intervalInfoAtTime.streamsInGapCount || 0,\n currentStreamsInGapCount = this._streamsInGapCount;\n\n this._streamsInGapCount = newStreamsInGapCount;\n\n // Note that hypothetically we could have an edge case where\n // one stream enters a gap at the exact second that one leaves a gap.\n // We should investigate and consider possibly handling such an edge case (VID-33350).\n if (newStreamsInGapCount < currentStreamsInGapCount) {\n console.log(`The number of cameras in a gap decreased from ${currentStreamsInGapCount} to ${newStreamsInGapCount},\n seeking all cameras to ${_currentTime} to bring playback back in sync`);\n // We currently seek all players after a player exits a gap to re-sync them all.\n // We should investigate this solution further and consider possible improvements\n // to how this works in the future (VID-33354).\n this.seekToCurrentTime(camerasDataObject, intervalsControlDataForCurrentTime, false);\n return;\n }\n\n this.updateIsInGapStatus(camerasModel, streamsInfo);\n }\n\n const newTime = addSeconds(_currentTime, interval);\n\n if (!this._moveToNextAvailableStartTime(newTime)) {\n return;\n }\n\n this.startTimer(camerasDataObject, intervalsControlDataForCurrentTime);\n }\n\n /**\n * Sets the new speed for playback.\n */\n onSpeedChange(\n newSpeed: string | number,\n availableSpeeds: number[],\n camerasDataObject: CamerasDataObject,\n useHdStream: boolean\n ): void {\n const { _isPaused, _isTimelineButtonDisplayingPlayIcon, _playersControl } = this;\n\n // ensure that newSpeed is a number. (the initial toString is to make TS not complain)\n newSpeed = parseInt(newSpeed.toString());\n\n if (isNaN(newSpeed)) {\n throw new Error('Invalid input. The value of newSpeed is not a number.');\n }\n\n this._stats.logEvent(getSpeedDropdownEventEnum(newSpeed));\n\n // Only track loading time if it's playing.\n this._loadStartTime = _isPaused ? null : performance.now();\n // If this is a speed change on pause, we will use that information in the playStarted event.\n this._hasSetSpeedAfterPause = _isPaused;\n this.setSpeedValues(availableSpeeds.indexOf(newSpeed), availableSpeeds);\n this._seekTypeEnum = SpeedDropdown;\n\n // If we haven't pressed the play button yet then no reason to queue a speed command.\n if (_isTimelineButtonDisplayingPlayIcon) {\n return;\n }\n\n this.updatePageAndPlayerState(FROZEN_STATE, ALL_CONNECTED_CAMERAS_ID, camerasDataObject.activeCameras);\n\n const playbackStateControllers = this._getPlaybackStateControllers();\n\n // WebRTC controls cannot be handled by playersControl since we're restarting the stream rather than\n // sending a command\n if (\n playbackStateControllers &&\n playbackStateControllers.some((controller) => controller instanceof WebRtcProxyPlaybackStateController)\n ) {\n this.setPlayerUrlsForAllCameraItems(camerasDataObject, useHdStream);\n }\n\n _playersControl.setSpeed(newSpeed);\n }\n\n /**\n * Pauses playback on the player.\n */\n pause(camerasDataObject: CamerasDataObject): void {\n const { _playersControl } = this,\n { activeCameras, camerasModel } = camerasDataObject;\n\n if (this.pageState === READY_STATE) {\n // we are already paused, so do nothing here\n return;\n }\n\n this.updatePageAndPlayerState(READY_STATE, ALL_CONNECTED_CAMERAS_ID, activeCameras);\n this._stats.logEvent(Pause);\n\n this._hasSeekedAfterPause = false;\n this._isTimelineButtonDisplayingPlayIcon = true;\n this._isPaused = true;\n this._isPlaying = false;\n\n setCameraProperties(\n camerasModel,\n {\n isPaused: true,\n isPlaying: false\n },\n ALL_CONNECTED_CAMERAS_ID\n );\n\n _playersControl.pause();\n this.stopTimer();\n }\n\n /**\n * Resets video source information and gets fresh recording intervals to restart the stream.\n */\n refreshVideoSource(\n globalDeviceId: string,\n camerasDataObject: CamerasDataObject,\n useHdStream: boolean,\n playbackInfoCacheManager: PlaybackInfoCacheManager,\n getVideoSource: GetVideoSourceMethod\n ): void {\n const { _playerType } = this;\n\n // Reload the video source.\n getVideoSource(globalDeviceId, true).then(async (videoSource) => {\n if (!_playerType || !videoSource) {\n return;\n }\n\n this.resetPlaybackButtons(camerasDataObject.camerasModel);\n\n const cameraItem = getCameraItemByGlobalDeviceId(globalDeviceId, camerasDataObject.cameraItems);\n\n if (!cameraItem) {\n return;\n }\n\n await this.setPlayerUrlsForCameraItem(cameraItem, camerasDataObject, useHdStream);\n const intervals = await videoSource.intervals;\n\n playbackInfoCacheManager.addVideoSourceToCache(globalDeviceId, _playerType, videoSource);\n playbackInfoCacheManager.addIntervalsToCache(globalDeviceId, _playerType, intervals);\n });\n }\n\n /**\n * Report the playback loading time to WaveFront if playback was successful on the Onboard Timeline page.\n */\n private reportPlaybackLoadingTimeToWaveFront(\n loadStartTime: number,\n loadEndTime: number,\n playbackRestarted: boolean,\n seekTypeEnum: number,\n playbackSpeed: number\n ): void {\n // we only report this to wavefront on SD\n if (this._playerType !== StreamUsage.SDCard) {\n return;\n }\n\n if (!loadStartTime) {\n // If loadStartTime is not defined, then the video must have already been playing.\n // We do not want multiple metrics to be logged when this happens, and we do not want to throw an error.\n return;\n }\n\n if (!loadEndTime || !seekTypeEnum || loadStartTime > loadEndTime) {\n console.error(\n `Invalid metrics for WaveFront reporting: loadStartTime=${loadStartTime}, loadEndTime=${loadEndTime}, seekTypeEnum=${seekTypeEnum}.`\n );\n return;\n }\n\n const data = {\n loadTimeInMilliseconds: loadEndTime - loadStartTime,\n playbackRestarted,\n seekTypeEnum,\n playbackSpeed,\n useWebRtc: true\n };\n\n // It doesn't matter if the API request was successful or not because it's just logging metrics to WaveFront.\n // A failed request has no impact on the user, and this request does not block other events from occurring.\n this._ajax.apiRequest(\n 'video/videoSources/sdCardVideoSources/reportPlaybackLoadingTimeToWaveFront',\n undefined,\n data,\n POST\n );\n }\n\n /** * Puts the page in a stopped state\n */\n resetPlaybackButtons(camerasModel: Camera[]): void {\n const { _playersControl } = this;\n\n // If the player is still playing, OR the stream disconnected during startup (couldn't connect to stream).\n if (this._isPlaying || this.pageState === LOADING_STATE) {\n // Then we've probably reached the end of the stream, so let's reset the playback.\n // Streams given an end time should end gracefully. However, not all streams are given end times (i.e. 523/723 SD card streams).\n // They will continue to attempt to play even if it has reached the end.\n // Note: the playback can still work even past end time if there is newly recorded footage created during the time of the initial playback.\n // However, this feature isn't supported with the current state of the component and will create a negative user experience.\n _playersControl.reset();\n }\n\n this._initStarted = false;\n this._isPlaying = false;\n this._isTimelineButtonDisplayingPlayIcon = true;\n\n setCameraProperties(\n camerasModel,\n {\n isPlaying: false\n },\n ALL_CAMERAS_ID\n );\n\n _playersControl.reset();\n }\n\n /**\n * A helper to resume playback using the appropriate method.\n *\n * @param isUserResumeAction if this is triggered from a user resume action. (if false it might be because its triggered by a new time select action)\n * When triggered from a user resume action, we log a play event and retry the connection if disconnected\n */\n resumePlayback(\n useHdStream: boolean,\n camerasDataObject: CamerasDataObject,\n intervalsControlDataForCurrentTime: IntervalsControlDataForTime,\n isUserResumeAction: boolean\n ): void {\n const { _pageState, _playersControl } = this;\n\n if (_pageState === DISCONNECTED_STATE) {\n return;\n }\n\n // if this is from a user resume action we need to initialize/reset certain vars\n if (isUserResumeAction) {\n // Report any play button click to wavefront.\n this._stats.logEvent(Play);\n\n this._loadStartTime = performance.now();\n this._isTimelineButtonDisplayingPlayIcon = false;\n this._seekTypeEnum = Play;\n this._isPaused = false;\n }\n\n const playbackStateControllers = this._getPlaybackStateControllers();\n\n // We should make sure we load up the controller in the setPlayerUrlsForAllCameraItems call.\n if (playbackStateControllers) {\n this.updatePageAndPlayerState(FROZEN_STATE, ALL_CONNECTED_CAMERAS_ID, camerasDataObject.activeCameras);\n _playersControl.resume();\n this.handleSeekOrSpeedChangeAfterPause();\n // This must be done *before* setCameraProperties (below) so that the overlay transitions into Playing State correctly.\n this.seekToCurrentTime(camerasDataObject, intervalsControlDataForCurrentTime, useHdStream);\n return;\n }\n\n _playersControl.resume();\n\n if (_pageState === READY_STATE) {\n // If every player is in the ready state, force a restart to occur.\n this.startVideoPlayback(true, useHdStream, camerasDataObject, intervalsControlDataForCurrentTime);\n }\n }\n\n /**\n * If the camera times out, retry the connection upon clicking the 'retry' button.\n */\n retryConnection(\n globalDeviceId: string,\n deviceIdsDisplayingOnPage: string[],\n camerasDataObject: CamerasDataObject,\n resetIntervalsAndStartPlayback: () => void\n ): void {\n const { _currentTime, _playerType, _timelineStartTime, _timelineEndTime } = this;\n\n if (!_currentTime || !_timelineStartTime || !_timelineEndTime) {\n return;\n }\n\n this._stats.logEvent(Retry);\n\n this.updatePageAndPlayerState(INITIALIZING_STATE, globalDeviceId, camerasDataObject.activeCameras);\n\n this.setSeekTypeEnum(AutoRetryConnection);\n\n this._playbackInfoCacheManager.addPlaybackTimesToCache(\n deviceIdsDisplayingOnPage,\n _playerType as number,\n _timelineStartTime,\n _timelineEndTime,\n _currentTime\n );\n\n this.resetPlaybackButtons(camerasDataObject.camerasModel);\n\n // Reset the coverage and re-prepare for playback.\n resetIntervalsAndStartPlayback();\n }\n\n /**\n * Attempts to seek to the current time.\n * If there exists a gap, then we should skip over it given that the end of the gap occurs within the currently loaded video.\n *\n * @param [defer=false] If set to true, send the seek request after a certain timeout.\n * If this method is called before that timeout is over, it'll be reset. This will lessen the number of requests to the server.\n *\n * @returns Whether or not the seek was successful.\n */\n seekToCurrentTime(\n camerasDataObject: CamerasDataObject,\n intervalsControlDataForCurrentTime: IntervalsControlDataForTime,\n useHdStream: boolean,\n defer = false\n ): boolean {\n const { camerasModel } = camerasDataObject;\n\n setCameraProperties(\n camerasModel,\n {\n isPlaying: false\n },\n ALL_CAMERAS_ID\n );\n\n const { _currentTime } = this,\n { intervalInfoAtTime } = intervalsControlDataForCurrentTime;\n\n // We are currently in a paused state. We shouldn't do anything.\n if (this._isTimelineButtonDisplayingPlayIcon) {\n return true;\n }\n\n if (!this._moveToNextAvailableStartTime(null)) {\n return false;\n }\n\n this.updatePageAndPlayerState(FROZEN_STATE, ALL_CONNECTED_CAMERAS_ID, camerasDataObject.activeCameras);\n\n const { streamsInfo } = intervalInfoAtTime;\n\n this._streamsInGapCount = intervalInfoAtTime.streamsInGapCount;\n this.updateIsInGapStatus(camerasModel, streamsInfo);\n\n // We don't want too many calls to seek on the player because it cannot handle that well.\n // If the user is quickly skipping forward/back, we just defer the call until they settle on a place.\n if (this._seekInterval) {\n // Do not copy this deprecated usage. If you see this, please fix.\n // eslint-disable-next-line ember/no-runloop\n cancel(this._seekInterval);\n }\n\n if (intervalInfoAtTime.isInGap) {\n // The request should be deferred to a later time, so we don't make too many API calls.\n if (defer) {\n // Do not copy this deprecated usage. If you see this, please fix.\n // eslint-disable-next-line ember/no-runloop\n this._seekInterval = later(\n this,\n this.seekToCurrentTime,\n camerasDataObject,\n intervalsControlDataForCurrentTime,\n useHdStream,\n false,\n DeferTimeoutPeriod\n );\n return true;\n }\n\n // Tell the user if we have reached the end of playback.\n this.disconnectPlaybackEnded(camerasDataObject);\n return false;\n }\n\n // Perform a seek for OESP streams.\n // playersControl should ignore sending the seek command to any WebRTC playback state controllers.\n this._playersControl.seek(_currentTime);\n\n const playbackStateControllers = this._getPlaybackStateControllers();\n\n // Performs a seek for WebRTC streams.\n if (\n playbackStateControllers &&\n playbackStateControllers.some((controller) => controller instanceof WebRtcProxyPlaybackStateController)\n ) {\n this.setPlayerUrlsForAllCameraItems(camerasDataObject, useHdStream);\n }\n\n return true;\n }\n\n /**\n * Sets the loading start time and playback restarted status for Wavefront logging.\n */\n setLoadStartTimeAndPlaybackRestartedForWavefrontLogging(): void {\n this._loadStartTime = performance.now();\n this._playbackRestarted = false;\n }\n\n /**\n * Sets player URLs to player objects and playback states controller.\n * We're assuming there's only ever one WebRTC playback controller.\n */\n async setPlayerUrlsForAllCameraItems(camerasDataObject: CamerasDataObject, useHdStream: boolean): Promise {\n // Make sure we are not in a gap when setting WebRTC URL.\n // Attempting to retrieve video at a time when there is no video\n // results in streaming errors and causes the player to disconnect.\n if (!this._moveToNextAvailableStartTime(null)) {\n return;\n }\n\n // Update all player objects with new URLs, wait for all to finish.\n await Promise.all(\n camerasDataObject.cameraItems.map(async (cameraItem) => {\n return this.setPlayerUrlsForCameraItem(cameraItem, camerasDataObject, useHdStream);\n })\n );\n\n // We need to wait a full Ember run cycle.\n // Ember doesn't call didUpdateAttrs immediately for the player object add-on,\n // so we need to finish the current loop so the player objects can update their URLs.\n // Once they have the correct URL, then we are safe to tell the playbackStateController updates.\n // Do not copy this deprecated usage. If you see this, please fix.\n // eslint-disable-next-line ember/no-runloop\n next(() => {\n const playbackStateControllers = this._getPlaybackStateControllers();\n\n if (!playbackStateControllers) {\n return;\n }\n\n playbackStateControllers.forEach((controller) => {\n if (controller instanceof WebRtcProxyPlaybackStateController) {\n controller.updateUrl();\n controller.playing = true;\n }\n });\n });\n }\n\n /**\n * Sets player URLs for a specified camera item.\n */\n private async setPlayerUrlsForCameraItem(\n cameraItem: CameraItem,\n camerasDataObject: CamerasDataObject,\n useHdStream: boolean\n ): Promise {\n const { _currentTime } = this,\n { player } = cameraItem,\n deviceId = player?.deviceId;\n\n if (!deviceId || !_currentTime) {\n return;\n }\n\n await this._setPlayerUrls(\n player,\n deviceId,\n _currentTime,\n addMinutes(_currentTime, PlaybackMaxBlockDuration)\n ).catch((error) => {\n // TODO: This ignore is an existing deprecation that must be refactored, do not copy this usage\n // eslint-disable-next-line @adc/ember/no-is-destroyed\n if (isDestroyed(this)) {\n return;\n }\n\n const errorEnum = error?.errorEnum ?? PlaybackServerConnectionFailed;\n\n this.handleDisconnectedPlaybackPlayer(errorEnum, deviceId, camerasDataObject);\n });\n\n const { playbackStateController } = player;\n\n if (playbackStateController instanceof OespPlaybackStateController) {\n playbackStateController.setupPlayers(null, 1, useHdStream);\n playbackStateController.startOespLiveRelay();\n }\n }\n\n /**\n * Sets the speed index and speed values\n */\n setSpeedValues(newSpeedIndex: number, availableSpeeds: number[]): void {\n this._speedIndex = newSpeedIndex;\n this._speed = availableSpeeds[newSpeedIndex];\n }\n\n /**\n * Sets the timeline to show the entire 24-hour period of the current day.\n */\n setTimelineBoundsToMidnight(): void {\n const { currentTime, _timezone } = this;\n\n if (!currentTime) {\n return;\n }\n\n /**\n * Shift the date by the offset between the account's timezone and\n * the browser's timezone.\n */\n const localCurrentTime = utcToZonedTime(currentTime, _timezone),\n startOfLocalCurrentDay = startOfDay(localCurrentTime),\n // Subtracting one second from this so the timeline shows 11:59pm instead of 12:00am.\n endOfLocalCurrentDay = addSeconds(startOfLocalCurrentDay, NUM_SECONDS_IN_DAY - 1),\n /**\n * Shift off the offset between the account's timezone and the browser's\n * timezone.\n */\n timelineStartTime = zonedTimeToUtc(startOfLocalCurrentDay, _timezone),\n timelineEndTime = zonedTimeToUtc(endOfLocalCurrentDay, _timezone);\n\n this._timeInterval = 1 + differenceInSeconds(timelineEndTime, timelineStartTime);\n this._timelineStartTime = timelineStartTime;\n this._timelineEndTime = timelineEndTime;\n }\n\n /**\n * Starts the timer.\n */\n private startTimer(\n camerasDataObject: CamerasDataObject,\n intervalsControlDataForCurrentTime: IntervalsControlDataForTime\n ): void {\n // Stops the timer to ensure we don't have multiple timers incrementing the current time at once.\n this.stopTimer();\n\n // Run a max of 4 times a second.\n const { _speed } = this,\n delay = Math.max(250, Math.floor(NUM_MILLISECONDS_IN_SECOND / _speed)),\n interval = Math.max(_speed / 4, 1);\n\n // Schedules the next tick.\n // Do not increment the timer during automated tests because this will never settle,\n // and any async functions that do \"await settled()\" will timeout.\n if (!this._isTestEnvironment) {\n // Do not copy this deprecated usage. If you see this, please fix.\n // eslint-disable-next-line ember/no-runloop\n this._tickInterval = later(() => {\n this.incrementTimer(camerasDataObject, interval, intervalsControlDataForCurrentTime);\n }, delay);\n }\n }\n\n /**\n * Sets the timeline start and end times\n */\n setTimelineTimes(timelineStartTime: Date | null, timelineEndTime: Date | null): void {\n this._timelineStartTime = timelineStartTime;\n this._timelineEndTime = timelineEndTime;\n }\n\n /**\n * Starts video playback based on the current parameter on the page.\n *\n * @param [isRestart=false] Was this function called as a stream restart?\n */\n async startVideoPlayback(\n isRestart = false,\n useHdStream: boolean,\n camerasDataObject: CamerasDataObject,\n intervalsControlDataForCurrentTime: IntervalsControlDataForTime\n ): Promise {\n const connectionStartTimeForStreamLogging = Date.now(),\n { activeCameras, camerasModel, cameraItems } = camerasDataObject;\n\n this._loadStartTime = performance.now();\n\n if (!this._moveToNextAvailableStartTime(null)) {\n return;\n }\n\n this._initStarted = false;\n this._isPlaying = false;\n this._playbackRestarted = isRestart;\n\n setCameraProperties(\n camerasModel,\n {\n connectionStartTime: connectionStartTimeForStreamLogging,\n hasStreamTimedOut: false,\n isPlaying: false\n },\n ALL_CAMERAS_ID\n );\n\n // currentTime needs to be retrieved after the call to moveToNextAvailableStartTime because that may update the value.\n const { currentTime, speed } = this;\n\n if (!currentTime) {\n return;\n }\n\n const { intervalInfoAtTime } = intervalsControlDataForCurrentTime,\n streamsInfo = intervalInfoAtTime?.streamsInfo;\n\n this.updateIsInGapStatus(camerasModel, streamsInfo, (globalDeviceId: string) => {\n // The loading state is set individually to prevent a flash of the loading bar upon starting.\n this.updatePageAndPlayerState(LOADING_STATE, globalDeviceId, activeCameras);\n });\n\n await Promise.all(\n cameraItems.map(async (cameraItem) => {\n const { player } = cameraItem,\n deviceId = player?.deviceId;\n\n if (!deviceId) {\n return;\n }\n\n await this._setPlayerUrls(\n player,\n deviceId,\n currentTime,\n addMinutes(currentTime, PlaybackMaxBlockDuration)\n )\n .then(() => {\n // TODO: This ignore is an existing deprecation that must be refactored, do not copy this usage\n // eslint-disable-next-line @adc/ember/no-is-destroyed\n if (isDestroyed(this)) {\n return;\n }\n\n this._initStarted = true;\n this._isTimelineButtonDisplayingPlayIcon = false;\n })\n .catch((error) => {\n // TODO: This ignore is an existing deprecation that must be refactored, do not copy this usage\n // eslint-disable-next-line @adc/ember/no-is-destroyed\n if (isDestroyed(this)) {\n return;\n }\n\n const errorEnum = error?.errorEnum ?? PlaybackServerConnectionFailed;\n this.handleDisconnectedPlaybackPlayer(errorEnum, deviceId, camerasDataObject);\n });\n })\n );\n\n const playbackStateControllers = this._getPlaybackStateControllers();\n\n if (!playbackStateControllers) {\n return;\n }\n\n playbackStateControllers.forEach((controller) => {\n if (!(controller instanceof WebRtcProxyPlaybackStateController) && implementsBasePlayer(controller)) {\n controller.setupPlayers(currentTime, speed, useHdStream);\n controller.startPlayback();\n }\n });\n }\n\n /**\n * Stops the timer.\n */\n private stopTimer(): void {\n if (this._tickInterval) {\n // Do not copy this deprecated usage. If you see this, please fix.\n // eslint-disable-next-line ember/no-runloop\n cancel(this._tickInterval);\n }\n }\n\n /**\n * Sets the current time accounting for all restrictions.\n *\n * @param newTime The new time to set the current time to.\n */\n updateCurrentTime(\n newTime: Date,\n intervalsControlData: IntervalsControlData,\n updateTimelineAndLoadThumbnailsAndEvents: (newTimelineStartTime: Date) => void\n ): void {\n const { _currentTime: oldCurrentTime } = this,\n { earliestRecord, latestRecord } = intervalsControlData;\n\n if (!earliestRecord || !latestRecord) {\n return;\n }\n\n if (isBefore(newTime, earliestRecord)) {\n newTime = earliestRecord;\n } else if (isAfter(newTime, latestRecord)) {\n newTime = latestRecord;\n }\n\n this._currentTime = newTime;\n const newTimelineStartTime = this.getTimelineChangeFromCurrentTimeChange(oldCurrentTime);\n\n if (newTimelineStartTime) {\n updateTimelineAndLoadThumbnailsAndEvents(newTimelineStartTime);\n }\n }\n\n /**\n * Sets the hasSeekedAfterPause variable to the current isPaused value\n */\n updateHasSeekedAfterPause(): void {\n this._hasSeekedAfterPause = this._isPaused;\n }\n\n /**\n * Sets the isInGap parameter on the cameras which determines whether we display the footage not available message.\n *\n * @param streamsInfo The info object that states which device is current in a gap.\n * @param isNotInGapCallback The action to take if the device is currently not in a gap.\n */\n private updateIsInGapStatus(\n camerasModel: Camera[],\n streamsInfo?: StreamsInfoAtTime,\n isNotInGapCallback?: (globalDeviceId: string) => void\n ): void {\n streamsInfo?.forEach((streamInfo) => {\n const { globalDeviceId, isInGap } = streamInfo;\n\n setCameraProperties(\n camerasModel,\n {\n isInGap\n },\n globalDeviceId || ''\n );\n\n if (!isInGap) {\n isNotInGapCallback && isNotInGapCallback(globalDeviceId || '');\n }\n });\n }\n\n /**\n * Changes the page and player state, so that the overlay on the player and page controls changes appropriately.\n *\n * @param newState The state to change the page and player state to (e.g. playing, initializing, loading, frozen, disconnected, or ready).\n * @param globalDeviceId\n * @param errorEnum The stream connection error enum. The error enum cannot be NO_ERROR if newState is DISCONNECTED_STATE.\n */\n updatePageAndPlayerState(\n newState: number,\n globalDeviceId: string,\n activeCameras: Camera[] | null,\n errorEnum = NoError\n ) {\n if (newState === DISCONNECTED_STATE && errorEnum === NoError) {\n sentryWithScopeAndWarn(\n 'Unexpected behavior: Setting pageState to DISCONNECTED_STATE with errorEnum = NoError',\n { deviceId: globalDeviceId }\n );\n }\n\n const { _pageState } = this;\n\n // Modify the state of each individual player.\n setCameraProperties(\n activeCameras,\n {\n playerState: newState,\n streamConnectionErrorEnum: errorEnum,\n loadingPercentage: 0\n },\n globalDeviceId\n );\n\n const playerStates =\n activeCameras?.map((camera) => {\n // this should never be null, but need to check because of TS\n if (camera.playerState == null) {\n return PLAYING_STATE;\n }\n\n return camera.playerState;\n }) || [];\n\n newState = this.calculatePageState(playerStates);\n\n if (_pageState === newState) {\n return;\n }\n\n const newStateString = this.convertCurrentStateEnumToString(newState),\n oldStateString = this.convertCurrentStateEnumToString(_pageState),\n errorString = newState === DISCONNECTED_STATE ? `, ${convertErrorEnumToString(errorEnum)}` : '';\n\n console.log(`Changing state: ${oldStateString} -> ${newStateString}${errorString}`);\n\n // Modify the state of the page. This is equivalent to the state of the player if we're not using video-streaming-players.\n this._pageState = newState;\n }\n\n /**\n * Updates the state of the timer on the playback page. It'll be completely dependent on the page state.\n */\n updatePageControls(\n camerasDataObject: CamerasDataObject,\n intervalsControlDataForCurrentTime: IntervalsControlDataForTime\n ): void {\n if (this._pageState === PLAYING_STATE) {\n this.startTimer(camerasDataObject, intervalsControlDataForCurrentTime);\n return;\n }\n\n this.stopTimer();\n }\n\n /**\n * Updates the commands for the camera provided\n */\n updatePlayersControlCommands(cameraIndex: null | number, commandFunctions: VoidFunction[]): void {\n this._playersControl.updateCommands(cameraIndex, commandFunctions);\n }\n\n /**\n * Updates start and end times.\n * Returns true if the timelineStartTime or timelineEndTime have changed\n */\n updateTimeline(newStartTime: Date, earliestRecord?: Date | null, latestRecord?: Date | null): boolean {\n const { _timelineStartTime, _timelineEndTime, _timeInterval } = this;\n\n if (!earliestRecord || !latestRecord || !_timeInterval) {\n return false;\n }\n\n // Do not let the new start time be before the earliest record.\n if (isBefore(newStartTime, earliestRecord)) {\n newStartTime = earliestRecord;\n }\n\n let newEndTime = addSeconds(newStartTime, _timeInterval - 1);\n\n // Do not let the new end time be after the latest record.\n if (isAfter(newEndTime, latestRecord)) {\n newStartTime = subSeconds(latestRecord, _timeInterval - 1);\n }\n\n newEndTime = addSeconds(newStartTime, _timeInterval - 1);\n\n this._timelineStartTime = newStartTime;\n this._timelineEndTime = newEndTime;\n\n if (_timelineStartTime !== newStartTime || _timelineEndTime !== newEndTime) {\n return true;\n }\n\n return false;\n }\n\n /**\n * Sets the pageState when the user seeks to a new time or modifies the playback speed.\n */\n updateToFrozenStateIfValid(activeCameras: Camera[] | null): void {\n // If pageState is playing, change to frozen.\n // If pageState is initializing, loading, frozen, or ready, keep the pageState as it was.\n if (this._pageState === PLAYING_STATE) {\n this.updatePageAndPlayerState(FROZEN_STATE, ALL_CONNECTED_CAMERAS_ID, activeCameras);\n }\n }\n}\n","import { precompileTemplate } from \"@ember/template-compilation\";\nexport default precompileTemplate(\"
  • \\n \\n
  • \\n\",{ moduleName: \"customer-site/components/video/event-history-item/index.hbs\" })","/* import __COLOCATED_TEMPLATE__ from './index.hbs'; */\nimport Component from '@glimmer/component';\nimport { action, computed, getProperties } from '@ember/object';\nimport { inject as service } from '@ember/service';\nimport { intlPath } from '@adc/i18n/path';\nimport { Animal, Human, Vehicle, Unknown } from '../../../enums/ClassificationCategoryType';\nimport { VideoCameraTriggered, VideoEventTriggered } from '../../../enums/EventType';\nimport { classificationIconLookup } from '../../../utils/video/general';\n\nimport type ADCIntlService from '@adc/i18n/services/adc-intl';\nimport type HistoryEvent from 'customer-site/models/activity/history-event';\n\ntype EventItem = { icon: string } & Pick;\n\ninterface EventHistoryItemSignature {\n Args: {\n event: HistoryEvent;\n onEventClick(event: HistoryEvent): void;\n };\n Element: HTMLButtonElement;\n}\n\n/**\n * @classdesc\n *\n * Displays a event history list item.\n */\n@intlPath({ path: 'video/event-history-item' })\nexport default class EventHistoryItem extends Component {\n @service declare intl: ADCIntlService;\n\n /**\n * eventItem object. Will modify the original event item for events with ov classifications.\n */\n @computed('args.event')\n get eventItem(): EventItem {\n const { event } = this.args,\n isVideoEvent = event.eventType === VideoCameraTriggered || event.eventType === VideoEventTriggered,\n ovMapping: Record = {\n [Human]: { icon: classificationIconLookup(Human), description: this.intl.tc(this, 'ovPerson') },\n [Vehicle]: { icon: classificationIconLookup(Vehicle), description: this.intl.tc(this, 'ovVehicle') },\n [Animal]: { icon: classificationIconLookup(Animal), description: this.intl.tc(this, 'ovAnimal') },\n [Unknown]: { icon: classificationIconLookup(Unknown), description: this.intl.tc(this, 'ovOther') }\n };\n\n return {\n ...getProperties(event, 'deviceDescription', 'description', 'eventDate'),\n ...((isVideoEvent && ovMapping[event.ovClassification]) || {\n icon: event.iconData.icon\n })\n };\n }\n\n /**\n * Calls args.onClickEvent and blurs the target when event is clicked\n */\n @action\n click(event: MouseEvent) {\n if (event.target instanceof HTMLElement) {\n //Remove the autofocus once an event is clicked so that the space/enter can still be used to pause/play\n event.target.blur();\n }\n this.args.onEventClick(this.args.event);\n }\n}\n\ndeclare module '@glint/environment-ember-loose/registry' {\n export default interface Registry {\n 'Video::EventHistoryItem': typeof EventHistoryItem;\n }\n}\n","import { precompileTemplate } from \"@ember/template-compilation\";\nexport default precompileTemplate(\"
    \\n
    \\n
    \\n {{#if this.showFilter}}\\n \\n {{t \\'generic.filter\\'}}\\n {{else}}\\n {{tc this \\'activity\\'}}\\n
    \\n \\n {{#unless @usingDefaultFilter}}\\n \\n {{/unless}}\\n
    \\n {{/if}}\\n {{#unless @usingDefaultFilter}}\\n {{tc this \\'clearFilter\\'}}\\n {{/unless}}\\n
    \\n \\n
    \\n {{#if this.showFilter}}\\n
    \\n
    \\n
      \\n {{#if this.historyEventFiltersDropdownItems}}\\n
    • \\n

      {{t \\'generic.eventType\\'}}

      \\n \\n
    • \\n {{/if}}\\n {{#if this.deviceTypesFiltersDropdownItems}}\\n
    • \\n

      {{t \\'generic.deviceType\\'}}

      \\n \\n
    • \\n {{/if}}\\n
    • \\n

      {{t \\'generic.deviceName\\'}}

      \\n \\n
    • \\n
    \\n
    \\n
    \\n
    \\n \\n \\n
    \\n {{else}}\\n {{!-- This value is null while events are loading, so show the loading spinner on the activity sidebar. --}}\\n {{!-- Empty arrays are treated as false in the template (unlike JS), so an explicit null check is needed. --}}\\n {{#unless (eq @events null)}}\\n {{#if this.eventsToShow}}\\n
    \\n
    \\n
      \\n {{#each-in this.eventsDisplay as |day singleDayEvents|}}\\n
      \\n

      {{day}}

      \\n {{#each singleDayEvents as |event|}}\\n \\n \\n
      \\n {{/each}}\\n
    \\n {{/each-in}}\\n \\n
    \\n
    \\n {{else}}\\n
    \\n
    \\n

    {{t \\'generic.events.noEvents\\'}}

    \\n
    \\n
    \\n {{/if}}\\n {{else}}\\n \\n {{/unless}}\\n {{/if}}\\n\\n\",{ moduleName: \"customer-site/components/video/event-history/index.hbs\" })","/* import __COLOCATED_TEMPLATE__ from './index.hbs'; */\nimport Component from '@glimmer/component';\nimport { tracked } from '@glimmer/tracking';\nimport { computed, action } from '@ember/object';\nimport { inject as service } from '@ember/service';\nimport { type Registry as ServiceRegistry } from '@ember/service';\nimport { isEmpty } from '@ember/utils';\nimport {\n COOKIE_DEVICE_TYPES,\n COOKIE_HISTORY_EVENTS,\n getCookieForPage,\n storeCookieForPage\n} from 'customer-site/utils/video/cookies';\nimport { intlPath } from '@adc/i18n/path';\nimport { default as DropdownSelectItem, SELECTED, UNSELECTED } from '@adc/ui-components/utils/dropdown-select-item';\nimport { Animal, Human, Vehicle, Unknown } from '../../../enums/ClassificationCategoryType';\nimport { VideoCameraTriggered, VideoEventTriggered, UserSelected } from '../../../enums/EventType';\nimport { classificationIconLookup } from '../../../utils/video/general';\n\nimport './_style.scss';\nimport type HistoryDeviceIdFilter from 'customer-site/models/activity/history-device-id-filter';\nimport type HistoryDeviceTypeFilter from 'customer-site/models/activity/history-device-type-filter';\nimport type HistoryEvent from 'customer-site/models/activity/history-event';\nimport type HistoryEventFilter from 'customer-site/models/activity/history-event-filter';\nimport type { CameraItem } from '../video-streaming/video-streaming-features/types';\n\nexport type FilterFunction = (\n eventId: number,\n deviceTypeFilterIds: number[],\n ovClassification: number,\n globalDeviceId: string\n) => boolean;\n\ninterface VideoEventHistorySignature {\n Element: HTMLDivElement;\n Args: {\n cameraItems: CameraItem[]; // The list of cameras to be loaded into the device name dropdown\n closeThis: () => void;\n currentFilter: FilterFunction;\n devices: HistoryDeviceIdFilter[]; // List of filterable devices\n deviceTypes: HistoryDeviceTypeFilter[]; // List of filterable device types\n eventHover: (events: string[]) => void;\n events: HistoryEvent[] | null; // The list of events to be loaded into the event history list.\n filterApplied: (filterFn: FilterFunction) => void;\n hasVideoAnalyticsReadAccess: boolean; // Does this user have access to view analytics information?\n highlightedEventIds: string[]; // List of event ids hovered over from anywhere in the video timeline component\n historyEventFilters: HistoryEventFilter[] | null; // List of filterable event types\n isHidden: boolean;\n loadEventHistory: () => void;\n onClick: (event: HistoryEvent) => void;\n updateUsingDefaultFilterStatus?: (usingDefaultFilter: boolean) => void;\n usingDefaultFilter: boolean; // If we are currently using the default event filtering for the selected device/s.\n };\n}\n\ntype Cookie = {\n val: string;\n state: string;\n};\n\n/**\n * Helper function to filter ov classifications. This function will only be called\n * when we are certain the clip has OV classifications.\n *\n * @param ovClassification Best OV classification for event\n * @param videoClips Array of OV classifications selected\n *\n * @returns True if the camera was triggered by an OV classification\n *\n * @private\n */\nfunction clipHasOvClassification(ovClassification: number, videoClips: string[]): boolean {\n return videoClips.map(Number).includes(ovClassification);\n}\n\n/**\n * Helper function to create dropdown filters for the model\n *\n * @param name Event filter item description\n * @param value Event filter item value used for filtering.\n * @param icon Event filter item icon\n * @param isOvItem Is this dropdown item for OV classification?\n * @param state is this dropdown item initialized to be selected or unselected?\n */\nfunction createDropDownItem(\n name: string,\n value: string,\n icon: string,\n isOvItem = false,\n state = SELECTED\n): DropdownSelectItem {\n return DropdownSelectItem.create({\n name,\n value,\n icon,\n isOvItem,\n state\n });\n}\n\n/**\n * Sets the initial selected filters for the device. This will be the event filters stored in the cookie if a cookie is found and ignoreCookies is false.\n * Otherwise it will be the default filter values.\n *\n * @param ignoreCookies if true, ignore any saved cookies and just set the filters to the default values\n * @returns returns true if we successfully set default/cookie values\n */\nfunction setDefaultOrCookieSelections(this: VideoEventHistory, ignoreCookies: boolean): boolean {\n const {\n deviceIdFiltersDropdownItems,\n defaultSelectedDeviceIds,\n deviceTypesFiltersDropdownItems,\n historyEventFiltersDropdownItems\n } = this;\n\n if (!deviceTypesFiltersDropdownItems || !historyEventFiltersDropdownItems) {\n // Most likely we got here too early.\n return false;\n }\n\n // initializing to empty array so that when we call filter it doesn't crash.\n let deviceTypesCookie: Cookie[] = [],\n historyEventsCookie: Cookie[] = [];\n\n if (!ignoreCookies) {\n const routeName = this.contextManager.currentRouteData?.routeName,\n deviceTypesCookieJson = getCookieForPage.call(this, routeName, COOKIE_DEVICE_TYPES),\n historyEventsCookieJson = getCookieForPage.call(this, routeName, COOKIE_HISTORY_EVENTS);\n deviceTypesCookie = deviceTypesCookieJson ? JSON.parse(deviceTypesCookieJson) : [];\n historyEventsCookie = historyEventsCookieJson ? JSON.parse(historyEventsCookieJson) : [];\n }\n\n if (deviceIdFiltersDropdownItems[0].hasSubitems) {\n deviceIdFiltersDropdownItems[0].subitems.forEach((item) => {\n item.set('state', defaultSelectedDeviceIds.includes(item.value) ? SELECTED : UNSELECTED);\n });\n }\n\n if (deviceTypesFiltersDropdownItems[0].hasSubitems) {\n deviceTypesFiltersDropdownItems[0].subitems.forEach((item) => {\n const foundCookieForItem = deviceTypesCookie.find((cookieValue) => cookieValue.val === item.value);\n\n // Set the dropdown item to the cookie's value if found, otherwise set to selected.\n item.set('state', foundCookieForItem ? foundCookieForItem.state : SELECTED);\n });\n }\n\n if (historyEventFiltersDropdownItems[0].hasSubitems) {\n historyEventFiltersDropdownItems[0].subitems.forEach((item) => {\n const foundCookieForItem = historyEventsCookie.find((cookieValue) => cookieValue.val === item.value);\n\n item.set('state', foundCookieForItem ? foundCookieForItem.state : SELECTED);\n });\n }\n\n return true;\n}\n\n/**\n * If the dropdown filters that are currently selected are the same as the default filters for the selected device/s.\n */\nfunction dropdownsSelectedAreDefault(this: VideoEventHistory): boolean {\n const {\n deviceIdFiltersDropdownItems,\n defaultSelectedDeviceIds,\n deviceTypesFiltersDropdownItems,\n historyEventFiltersDropdownItems\n } = this;\n\n if (deviceIdFiltersDropdownItems[0].hasSubitems) {\n const selectedDevices = deviceIdFiltersDropdownItems[0].subitems.filter((item) => item.state === SELECTED);\n\n if (selectedDevices.length !== defaultSelectedDeviceIds.length) {\n return false;\n }\n\n if (!selectedDevices.every((device) => defaultSelectedDeviceIds.includes(device.value))) {\n return false;\n }\n }\n\n if (deviceTypesFiltersDropdownItems?.[0].hasSubitems) {\n const unselectedDeviceTypes = deviceTypesFiltersDropdownItems[0].subitems.filter(\n (item) => item.state !== SELECTED\n );\n\n // device types are all selected by default\n if (unselectedDeviceTypes.length) {\n return false;\n }\n }\n\n if (historyEventFiltersDropdownItems?.[0].hasSubitems) {\n const unselectedEventFilters = historyEventFiltersDropdownItems[0].subitems.filter(\n (item) => item.state !== SELECTED\n );\n\n // event filters are all selected by default\n if (unselectedEventFilters.length) {\n return false;\n }\n }\n\n return true;\n}\n\n/**\n * Stores the selected device type filters and history event filters into a cookie for the page\n */\nfunction storeFiltersToCookie(this: VideoEventHistory): void {\n const { deviceTypesFiltersDropdownItems, historyEventFiltersDropdownItems } = this;\n\n if (deviceTypesFiltersDropdownItems?.[0].hasSubitems) {\n const dropdownMap = deviceTypesFiltersDropdownItems[0].subitems.map((item) => ({\n val: item.value,\n state: item.state\n }));\n\n storeCookieForPage.call(this, COOKIE_DEVICE_TYPES, JSON.stringify(dropdownMap), false);\n }\n\n if (historyEventFiltersDropdownItems?.[0].hasSubitems) {\n const dropdownMap = historyEventFiltersDropdownItems[0].subitems.map((item) => ({\n val: item.value,\n state: item.state\n }));\n\n storeCookieForPage.call(this, COOKIE_HISTORY_EVENTS, JSON.stringify(dropdownMap), false);\n }\n}\n\n/**\n * @classdesc\n * Displays a scrollable event history list.\n */\n@intlPath({ path: 'video.event-history' })\nexport default class VideoEventHistory extends Component {\n tagName = '';\n\n @service declare intl: ServiceRegistry['adc-intl'];\n @service declare cookieManager: ServiceRegistry['cookie-manager'];\n @service declare contextManager: ServiceRegistry['context-manager'];\n\n @tracked initialFilterApplied = false;\n\n @tracked showFilter = false;\n\n /**\n * The filtered, sorted, and grouped events to be displayed.\n */\n @computed('args.{currentFilter,events}')\n get eventsDisplay(): Record {\n const { currentFilter, events } = this.args,\n filteredEvents = events?.filter(\n (event) =>\n !currentFilter ||\n currentFilter(\n event.get('eventType'),\n event.get('deviceTypeFilter'),\n event.get('ovClassification'),\n event.get('globalDeviceId')\n )\n ),\n // Sort the events by date in descending order.\n sortedEvents = filteredEvents?.sortBy('eventDate').reverse();\n\n const groupedEvents: Record = {};\n sortedEvents?.forEach((event) => {\n // Do not copy this deprecated usage. If you see this, please fix it\n // eslint-disable-next-line @adc/ember/require-tz-functions\n const day = this.intl.formatDate(event.eventDate, {\n day: 'numeric',\n month: 'short',\n year: 'numeric'\n });\n\n if (groupedEvents[day]) {\n groupedEvents[day].push(event);\n } else {\n groupedEvents[day] = [event];\n }\n });\n\n return groupedEvents;\n }\n\n /**\n * Is there at least one event to display?\n */\n @computed('eventsDisplay')\n get eventsToShow(): number {\n return Object.keys(this.eventsDisplay).length;\n }\n\n /**\n * Computes event types filter dropdown.\n */\n @computed('args.{hasVideoAnalyticsReadAccess,historyEventFilters.isFulfilled}')\n get historyEventFiltersDropdownItems(): DropdownSelectItem[] | null {\n const { intl, args } = this,\n { hasVideoAnalyticsReadAccess, historyEventFilters } = args;\n\n if (!historyEventFilters) {\n return null;\n }\n\n const eventTypeFilterItems = historyEventFilters.reduce(\n (accumulated: DropdownSelectItem[], { description, events, filterIcon }) => {\n // split Video Clips events into separate events for person, animal, car, and other detection.\n if (events?.includes(VideoCameraTriggered) || events?.includes(VideoEventTriggered)) {\n accumulated.pushObjects([\n createDropDownItem(\n intl.t('generic.video.videoClipsCameraTriggered'),\n VideoCameraTriggered.toString(),\n classificationIconLookup(VideoCameraTriggered)\n ),\n createDropDownItem(\n intl.t('generic.video.videoClipsEventTriggered'),\n VideoEventTriggered.toString(),\n classificationIconLookup(VideoEventTriggered)\n ),\n createDropDownItem(\n intl.t('generic.video.videoClipsUserSelected'),\n UserSelected.toString(),\n classificationIconLookup(UserSelected)\n )\n ]);\n\n if (hasVideoAnalyticsReadAccess) {\n accumulated.pushObjects([\n createDropDownItem(\n intl.tc(this, 'vidClipsPerson'),\n Human.toString(),\n classificationIconLookup(Human),\n true\n ),\n createDropDownItem(\n intl.tc(this, 'vidClipsAnimal'),\n Animal.toString(),\n classificationIconLookup(Animal),\n true\n ),\n createDropDownItem(\n intl.tc(this, 'vidClipsCar'),\n Vehicle.toString(),\n classificationIconLookup(Vehicle),\n true\n ),\n createDropDownItem(\n intl.tc(this, 'vidClipsOther'),\n Unknown.toString(),\n classificationIconLookup(Unknown),\n true\n )\n ]);\n }\n\n return accumulated;\n }\n\n return accumulated.pushObjects([createDropDownItem(description, events?.toString(), filterIcon)]);\n },\n []\n );\n\n // Create a big wrapper to give dropdown an all|none options\n return [\n DropdownSelectItem.create({\n name: this.intl.t('generic.eventTypes'),\n isSelectable: false,\n showAllNoneSelectors: true,\n subitems: eventTypeFilterItems\n })\n ];\n }\n\n /**\n * Computes device type filter dropdown\n */\n @computed('args.deviceTypes.isFulfilled')\n get deviceTypesFiltersDropdownItems(): DropdownSelectItem[] | null {\n if (!this.args.deviceTypes) {\n return null;\n }\n\n // Filter out 'All Devices' device type filter.\n const filters = this.args.deviceTypes.filter((f) => f.id !== '0');\n\n // Create a big wrapper to give dropdown an all|none options\n return [\n DropdownSelectItem.create({\n name: this.intl.t('generic.deviceTypes'),\n isSelectable: false,\n showAllNoneSelectors: true,\n subitems: (isEmpty(filters) ? [] : filters).map(({ description, id, filterIcon }) => {\n return createDropDownItem(description, id, filterIcon);\n })\n })\n ];\n }\n\n /**\n * Creates device names dropdown. Will do initial filtering for each camera selection.\n */\n @computed('args.{cameraItems.@each.model,devices.isFulfilled}')\n get deviceIdFiltersDropdownItems(): DropdownSelectItem[] {\n const subitems = (isEmpty(this.args.devices) ? [] : this.args.devices).map(\n ({ description, globalDeviceId, filterIcon }) => {\n return createDropDownItem(description, globalDeviceId, filterIcon, false, UNSELECTED);\n }\n );\n\n // Create a big wrapper to give dropdown an all|none options\n return [\n DropdownSelectItem.create({\n name: this.intl.t('generic.devices.devices'),\n isSelectable: false,\n showAllNoneSelectors: true,\n subitems\n })\n ];\n }\n\n /**\n * An array listing of the default devices that should start out selected, based on the devices/cameraItems passed in\n */\n @computed('args.{cameraItems.@each.model,devices.isFulfilled}')\n get defaultSelectedDeviceIds(): string[] {\n const devices = isEmpty(this.args.devices) ? [] : this.args.devices;\n\n return devices\n .filter((device) => {\n const { globalDeviceId, isCameraDevice } = device;\n\n return !isCameraDevice || this.args.cameraItems.mapBy('model.id').includes(globalDeviceId);\n })\n .mapBy('globalDeviceId');\n }\n\n /**\n * Applies the filters to the event list and notifies the application of the change.\n */\n @action applyFilters(): void {\n const { historyEventFiltersDropdownItems, deviceTypesFiltersDropdownItems, deviceIdFiltersDropdownItems } =\n this;\n // Get the user selected event types and video clips\n const selectedEventTypes: number[] = [],\n clipsWithOvClassification: string[] = [];\n historyEventFiltersDropdownItems?.[0].subitems.filterBy('state', SELECTED).forEach((filter) => {\n // Check if this is a Video Clip. If so we want to filter more specifically by description.\n if (filter.isOvItem) {\n clipsWithOvClassification.push(filter.value);\n return;\n }\n\n // Push associated event ids as array and get rid of duplicates.\n selectedEventTypes.pushObjects(filter.value.split(',').map(Number)).uniq();\n });\n\n // Get the user selected device types and selected devices\n const selectedDeviceTypes = deviceTypesFiltersDropdownItems?.[0].subitems\n .filterBy('state', SELECTED)\n .mapBy('value')\n .map(Number);\n const selectedDevices = deviceIdFiltersDropdownItems?.[0].subitems.filterBy('state', SELECTED).mapBy('value');\n\n const filterFn = (\n eventId: number,\n deviceTypeFilterIds: number[],\n ovClassification: number,\n globalDeviceId: string\n ) => {\n return (\n (selectedEventTypes.includes(eventId) ||\n clipHasOvClassification(ovClassification, clipsWithOvClassification)) &&\n !!selectedDeviceTypes?.some((dev) => deviceTypeFilterIds.indexOf(dev) >= 0) &&\n selectedDevices.includes(globalDeviceId)\n );\n };\n\n this.showFilter = false;\n\n // Notifies the application of the new filter function to use for other components.\n this.args.filterApplied(filterFn);\n\n // Reload history\n this.args.loadEventHistory();\n\n storeFiltersToCookie.call(this);\n\n this.args.updateUsingDefaultFilterStatus &&\n this.args.updateUsingDefaultFilterStatus(dropdownsSelectedAreDefault.call(this));\n }\n\n /**\n * Sets the filters to the default filter and applies them\n */\n @action clearFilter(): void {\n setDefaultOrCookieSelections.call(this, true);\n this.applyFilters();\n }\n\n /**\n * Any time the cameraItems are changed (the user either loaded the page or selected new devices) we set initialFilterApplied to false.\n * Immediately after this, the dropdown items will also recompute (because they are watching for cameraItems changes), which will trigger\n * onFilterItemsChanged. which will then retrieve the events matching the search\n */\n @action onCameraItemsChanged(): void {\n this.initialFilterApplied = false;\n }\n\n /**\n * When the selected filter items changes we should retrieve the events matching the search\n */\n @action onFilterItemsChanged(): void {\n const setDefaultOrCookieSuccessful = setDefaultOrCookieSelections.call(this, false);\n\n if (setDefaultOrCookieSuccessful && this.initialFilterApplied === false) {\n this.initialFilterApplied = true;\n this.applyFilters();\n }\n }\n}\n\ndeclare module '@glint/environment-ember-loose/registry' {\n export default interface Registry {\n 'Video::EventHistory': typeof VideoEventHistory;\n }\n}\n","import { precompileTemplate } from \"@ember/template-compilation\";\nexport default precompileTemplate(\"
    \\n \\n\\n
    \\n
    \\n {{t \\'generic.appliedFiltersCount\\' numFilters=@appliedFiltersCount}}\\n
    \\n\\n
    \\n {{#if @searchInProgress}}\\n
    \\n \\n
    \\n\\n {{t \\'generic.searching\\'}}\\n {{/if}}\\n\\n {{t \\'generic.resultsFound\\' resultCount=@resultCount}}\\n
    \\n\\n \\n
    \\n\\n
    \",{ moduleName: \"customer-site/components/video/advanced-video-search/results-status-bar/index.hbs\" })","/* import __COLOCATED_TEMPLATE__ from './index.hbs'; */\nimport Component from '@glimmer/component';\nimport { action } from '@ember/object';\nimport { inject as service } from '@ember/service';\nimport { getContextAwareSvrTimelinePage } from 'customer-site/video/svr-timeline/route';\nimport { intlPath } from '@adc/i18n/path';\n\nimport type DomService from '@adc/ember-utils/services/dom';\nimport type ContextManager from 'customer-site/services/context-manager';\nimport './_style.scss';\n\ninterface ResultsStatusBarSignature {\n Args: {\n appliedFiltersCount: number;\n cameraId: string | null;\n currentTime: Date | null;\n goBackToAvsSearch: () => void;\n pauseVideo: () => void;\n resultCount: number;\n timeInterval: number;\n searchInProgress?: boolean;\n };\n}\n\n/**\n * @classdesc\n * The avs status bar which indicates result information for the avs search\n */\n@intlPath({ path: 'video/advanced-video-search/results-status-bar' })\nexport default class ResultsStatusBar extends Component {\n @service declare contextManager: ContextManager;\n @service declare dom: DomService;\n\n /**\n * Adds key down listeners for shift+S and shift+A for going back to svr timeline or avs search\n */\n @action\n addKeyDownListeners() {\n this.dom.addListener(this, document, 'keydown', (event: KeyboardEvent) => {\n switch (event.key) {\n case 'S':\n this.navigateToSvrTimeline();\n return;\n case 'A':\n this.args.goBackToAvsSearch();\n return;\n }\n });\n }\n\n /**\n * Navigates to the SVR Timeline page with the selected device\n */\n @action\n navigateToSvrTimeline(): void {\n const svrTimelinePage = getContextAwareSvrTimelinePage(this.contextManager.isEnterprise);\n\n // TODO: This ignore is an existing deprecation that must be refactored, do not copy this usage\n // eslint-disable-next-line @adc/ember/no-context-manager-transition\n this.contextManager.transitionToRouteId(svrTimelinePage, {\n cameraId: this.args.cameraId,\n cameraGroupId: null,\n startTime: this.args.currentTime?.toISOString(),\n timeInterval: this.args.timeInterval\n });\n }\n\n /**\n * Navigate back to the AVS search page and also pause the video\n */\n @action\n goBackToSearchAndPauseVideo(): void {\n this.args.pauseVideo();\n this.args.goBackToAvsSearch();\n }\n}\n\ndeclare module '@glint/environment-ember-loose/registry' {\n export default interface Registry {\n 'Video::AdvancedVideoSearch::ResultsStatusBar': typeof ResultsStatusBar;\n }\n}\n","import { precompileTemplate } from \"@ember/template-compilation\";\nexport default precompileTemplate(\"\\n
    \\n {{#if @showThumbnails}}\\n
    \\n {{#each this.displayedSearchResults key=\\\"idx\\\" as |searchResult idx|}}\\n
    \\n\\n {{t\\n
    \\n {{searchResult.timeString}}\\n {{searchResult.rangeString}}\\n
    \\n
    \\n
    \\n {{/each}}\\n {{#if this.searchFailedOrInterrupted}}\\n
    \\n \\n {{this.errorText}}\\n \\n
    \\n {{/if}}\\n
    \\n\\n {{#if this.scrollAbility.canScrollLeft}}\\n
    \\n \\n
    \\n {{/if}}\\n\\n {{#if this.scrollAbility.canScrollRight}}\\n
    \\n \\n
    \\n {{/if}}\\n {{/if}}\\n
    \\n\\n\",{ moduleName: \"customer-site/components/video/advanced-video-search/found-search-results/index.hbs\" })","/* import __COLOCATED_TEMPLATE__ from './index.hbs'; */\nimport Component from '@glimmer/component';\nimport { tracked } from '@glimmer/tracking';\nimport { isEnterCode } from '@adc/ember-utils/utils/a11y';\nimport { constrainRange } from '@adc/ember-utils/utils/math';\nimport { action, computed } from '@ember/object';\nimport { alias } from '@ember/object/computed';\nimport { next } from '@ember/runloop';\nimport { inject as service } from '@ember/service';\nimport { htmlSafe } from '@ember/template';\nimport { getFullUrlForScrubberThumbnail } from 'customer-site/components/video/video-timeline/index';\nimport { TimelineClick } from 'customer-site/enums/TrackedEvent';\nimport { NUM_MILLISECONDS_IN_SECOND } from 'customer-site/utils/datetime';\nimport { intlPath } from '@adc/i18n/path';\nimport { isAfter, isBefore } from 'date-fns';\n\nimport type { Registry as ServiceRegistry } from '@ember/service';\nimport type Interval from 'customer-site/models/video/interval';\nimport type { SafeString } from 'handlebars';\nimport type { ScrubbedThumbnailUrls } from '../../video-player/playback-features/types';\nimport './_style.scss';\n\ntype DisplayedSearchResult = {\n idx: number;\n startTime: Date;\n timeString: string;\n rangeString: string;\n imageSource: string;\n};\n\ntype ScrollAbility = {\n canScrollLeft: boolean;\n canScrollRight: boolean;\n};\n\ninterface FoundSearchResultsSignature {\n Args: {\n changeSelectedResult: (index: number | undefined) => void;\n currentTime?: Date;\n isHidden: boolean;\n searchFailed: boolean;\n searchResults?: Interval[];\n searchWasInterrupted: boolean;\n selectedResultIndex: number | undefined;\n restartAvsSearch: () => void;\n showThumbnails: boolean;\n svrTimelineIsHidden: boolean;\n timelineNewTimeSet: (time: Date, timelineEnum: number) => void;\n thumbnailUrls: ScrubbedThumbnailUrls | null;\n pauseVideo: () => void;\n };\n Element: HTMLDivElement;\n}\n\n/*\n * Size of each individual results image (width plus margins) for calculating scroll amounts\n */\nconst ResultImageSize = 216;\n\n/*\n * Each time we scroll left or right, we want to scroll (number of players visible minus this amount of players)\n */\nconst ScrollFactor = 2;\n\n/**\n * Finds the next matching result index relative to the current time, either in the forward or backward direction\n * Returns null if the current time is after all of the results\n *\n * @returns\n */\nfunction findNextMatchingResultIndex(\n moveForwards: boolean,\n currentTime: Date,\n searchResults: Interval[],\n indexToStartFrom: number\n) {\n const resultsLength = searchResults.length;\n let indexToCheck = indexToStartFrom;\n\n while (indexToCheck < resultsLength && indexToCheck >= 0) {\n // If we are moving forward in time, lets keep moving forward until a result is either in the current time or after it\n // For backwards, lets keep moving backward until a result is either in the current time or before it.\n let goToThisResult = moveForwards\n ? isBefore(currentTime, searchResults[indexToCheck].endTime)\n : isAfter(currentTime, searchResults[indexToCheck].startTime);\n\n if (!moveForwards && indexToCheck == 0) {\n goToThisResult = true;\n }\n\n if (goToThisResult) {\n return indexToCheck;\n }\n\n indexToCheck += moveForwards ? 1 : -1;\n }\n\n // moving forward in time and getting past the end of the list is treated differently than moving backwards\n // and getting past the start of the list. We select the first result in the latter case, and stop playback in the former.\n return moveForwards ? null : 0;\n}\n\n/**\n * @classdesc\n * The avs status bar which indicates result information for the avs search\n */\n@intlPath({ path: 'video/advanced-video-search/found-search-results' })\nexport default class FoundSearchResults extends Component {\n @service declare contextManager: ServiceRegistry['context-manager'];\n @service declare intl: ServiceRegistry['adc-intl'];\n @service declare ajax: ServiceRegistry['ajax'];\n @service declare envSettings: ServiceRegistry['env-settings'];\n @service declare dom: ServiceRegistry['dom'];\n\n /**\n * How many pixels the list is currently scrolled (0 means not scrolled)\n */\n @tracked listScrollAmount = 0;\n\n /**\n * The width in pixels of this component\n */\n @tracked componentWidth = 0;\n\n /**\n * The number of results\n */\n @alias('args.searchResults.length')\n declare resultsLength: number;\n\n /**\n * If the result of the search was that it either failed or was interrupted\n */\n @computed('args.{searchFailed,searchWasInterrupted}')\n get searchFailedOrInterrupted(): boolean {\n return this.args.searchFailed || this.args.searchWasInterrupted;\n }\n\n /**\n * The error text to display for when a search is failed or interrupted\n */\n @computed('args.searchFailed', 'searchFailedOrInterrupted')\n get errorText(): string {\n if (!this.searchFailedOrInterrupted) {\n return '';\n }\n\n return this.args.searchFailed ? this.intl.t('generic.searchFailed') : this.intl.tc(this, 'searchCanceled');\n }\n\n /**\n * If the user can currently scroll left and right.\n */\n @computed('listScrollAmount', 'maxScrollDistance')\n get scrollAbility(): ScrollAbility {\n return {\n canScrollRight: this.listScrollAmount < this.maxScrollDistance,\n canScrollLeft: this.listScrollAmount > 0\n };\n }\n\n /**\n * The css style string for this element\n */\n @computed('listScrollAmount')\n get scrollPositionStyle(): SafeString {\n return htmlSafe(`left:-${this.listScrollAmount}px`);\n }\n\n /**\n * The displayed result objects\n */\n @computed('args.{searchResults,thumbnailUrls}')\n get displayedSearchResults(): Array | undefined {\n return this.args.searchResults?.map((searchResults, idx) => {\n const { startTime, endTime } = searchResults,\n { thumbnailUrls } = this.args,\n timeRange = (endTime.getTime() - startTime.getTime()) / NUM_MILLISECONDS_IN_SECOND;\n\n const imageSource = getFullUrlForScrubberThumbnail(\n this.envSettings,\n thumbnailUrls?.[0].url || '',\n startTime\n );\n\n const timeString = this.intl.formatDateTz(startTime, {\n hour: '2-digit',\n minute: '2-digit'\n });\n\n const rangeString = this.intl.t('generic.secondsCount', { seconds: Math.round(timeRange) });\n\n return {\n idx,\n startTime,\n timeString,\n rangeString,\n imageSource\n };\n });\n }\n\n /**\n * How far right the component can be scrolled in pixels. Basically, when we've reached the end of the results\n */\n @computed('componentWidth', 'displayedSearchResults', 'searchFailedOrInterrupted')\n get maxScrollDistance(): number {\n const { componentWidth, displayedSearchResults, searchFailedOrInterrupted } = this;\n\n let resultImagesLength = searchFailedOrInterrupted ? 1 : 0;\n\n if (!displayedSearchResults) {\n return resultImagesLength;\n }\n\n resultImagesLength += displayedSearchResults.length;\n\n return resultImagesLength * ResultImageSize - componentWidth;\n }\n\n /**\n * Information about which result indexes are fully visible, the first and the last.\n * Fully visible means it is 100% visible. (as opposed to part of the edge of it being hidden behind the edge)\n */\n @computed('listScrollAmount', 'componentWidth')\n get fullyVisibleImageResultRange() {\n const { listScrollAmount, componentWidth } = this;\n // doing ceil to ensure its fully visible\n const firstIndex = Math.ceil(listScrollAmount / ResultImageSize);\n // doing floor to ensure its fully visible, subtracting 1 because indexes start at 0 not 1\n const lastIndex = Math.floor((listScrollAmount + componentWidth) / ResultImageSize) - 1;\n\n return {\n firstIndex,\n lastIndex\n };\n }\n\n /**\n * Returns a scroll position which is bounded between 0 and this.maxScrollDistance\n */\n getBoundedScrollPosition(scrollPosition: number) {\n return constrainRange(scrollPosition, 0, this.maxScrollDistance);\n }\n\n /**\n * Calls changeSelectedResultAndPlaybackTime in the next iteration.\n */\n changeSelectedResultAndPlaybackTimeInNext(resultIndex: number) {\n // using next, otherwise ember doesnt like that currentTime is changing twice in the same cycle\n // Do not copy this deprecated usage. If you see this, please fix\n // eslint-disable-next-line ember/no-runloop\n next(() => {\n this.changeSelectedResultAndPlaybackTime(resultIndex);\n });\n }\n\n /**\n * Updates the component size value\n */\n @action\n updateComponentSize(el: HTMLDivElement): void {\n this.componentWidth = el.clientWidth;\n }\n\n /**\n * Scrolling the list of elements, forward or backward\n */\n @action\n scrollList(isForward: boolean): void {\n const { componentWidth, maxScrollDistance } = this,\n amountOfResultImagesVisible = Math.floor(componentWidth / ResultImageSize),\n imagesToScroll =\n amountOfResultImagesVisible > ScrollFactor ? amountOfResultImagesVisible - ScrollFactor : 1,\n scrollAmount = imagesToScroll * ResultImageSize;\n\n let newListScrollAmount = this.listScrollAmount;\n newListScrollAmount += isForward ? scrollAmount : -scrollAmount;\n newListScrollAmount = this.getBoundedScrollPosition(newListScrollAmount);\n\n const leftSideCutOffAmount = newListScrollAmount % ResultImageSize;\n\n // If we are scrolling backwards, lets make sure we aren't chopping off part of the first video\n if (!isForward) {\n newListScrollAmount -= leftSideCutOffAmount;\n } else {\n // If we are scrolling forwards, lets make sure we aren't chopping off part of the last video\n const leftSideCutOffAmountWhenMaxScrolled = maxScrollDistance % ResultImageSize;\n newListScrollAmount += leftSideCutOffAmountWhenMaxScrolled - leftSideCutOffAmount;\n }\n\n this.listScrollAmount = newListScrollAmount;\n }\n\n /**\n * Tells the parent component to navigate to the specified result index and start playback from then\n */\n @action\n changeSelectedResultAndPlaybackTime(index: number, event?: MouseEvent): void {\n const { args } = this,\n { searchResults } = args;\n\n if (!searchResults?.length) {\n return;\n }\n\n // stopping propagation otherwise the timeline component will also try to call the same method (but at the wrong time)\n event?.stopPropagation();\n\n this.args.changeSelectedResult(index);\n const searchResult = searchResults[index];\n args.timelineNewTimeSet(searchResult.startTime, TimelineClick);\n }\n\n /**\n * Goes to the selected result if the user hits ENTER\n */\n @action\n onKeyDownFromResult(index: number, event: KeyboardEvent): void {\n if (isEnterCode(event.key)) {\n this.changeSelectedResultAndPlaybackTime(index);\n }\n }\n\n /**\n * Restarts the same selected search\n */\n @action\n restartAvsSearch(): void {\n this.listScrollAmount = 0;\n this.args.restartAvsSearch();\n }\n\n /**\n * Whenever the currentTime updates (should be once a second) we make sure our selected result is still playing, otherwise we jump to the next result\n */\n @action\n onCurrentTimeUpdate(): void {\n const { args } = this,\n { currentTime, searchResults, selectedResultIndex, svrTimelineIsHidden } = args;\n\n if (!searchResults?.length || svrTimelineIsHidden || !currentTime) {\n return;\n }\n\n if (selectedResultIndex == null) {\n const closestResultIndex = findNextMatchingResultIndex(true, currentTime, searchResults, 0);\n\n if (closestResultIndex) {\n this.changeSelectedResultAndPlaybackTimeInNext(closestResultIndex);\n }\n return;\n }\n\n const selectedResult = searchResults[selectedResultIndex];\n\n if (!selectedResult) {\n return;\n }\n\n let moveForwards;\n\n if (isAfter(currentTime, selectedResult.endTime)) {\n moveForwards = true;\n } else if (isBefore(currentTime, selectedResult.startTime)) {\n moveForwards = false;\n } else {\n // the current time is inside of the selected result, so we dont need to do anything else\n return;\n }\n\n const indexToStartFrom = selectedResultIndex + (moveForwards ? 1 : -1);\n const nextMatchingResultIndex = findNextMatchingResultIndex(\n moveForwards,\n currentTime,\n searchResults,\n indexToStartFrom\n );\n\n if (nextMatchingResultIndex != null) {\n this.changeSelectedResultAndPlaybackTimeInNext(nextMatchingResultIndex);\n } else {\n this.changeSelectedResultAndPlaybackTimeInNext(0);\n\n // This isn't ideal. But changing the playback time and pausing the video at the same time tends to confuse playback features\n setTimeout(() => {\n this.args.pauseVideo();\n }, 1000);\n }\n }\n\n /**\n * Adds listeners for pressing down shift+H and shift+G for switching between results\n */\n @action\n addKeyDownListeners() {\n this.dom.addListener(this, document, 'keydown', (event: KeyboardEvent) => {\n const { resultsLength, args } = this,\n { isHidden, selectedResultIndex } = args;\n\n if (selectedResultIndex == null || isHidden) {\n return;\n }\n\n let newIndex = selectedResultIndex;\n\n switch (event.key) {\n case 'H':\n newIndex++;\n\n if (newIndex < resultsLength) {\n this.changeSelectedResultAndPlaybackTime(newIndex);\n }\n return;\n case 'G':\n newIndex--;\n\n if (newIndex >= 0) {\n this.changeSelectedResultAndPlaybackTime(newIndex);\n }\n return;\n }\n });\n }\n\n /**\n * If the isHidden value has updated to true (we went back to the search page), we reset the selected index and scroll values.\n */\n @action\n onVisibilityUpdate() {\n if (this.args.isHidden === true) {\n this.listScrollAmount = 0;\n }\n }\n\n /**\n * When the selected result changes, lets make sure it is fully visible, otherwise lets scroll to make it visible\n */\n @action\n onSelectedResultIndexUpdate() {\n const { componentWidth, args, fullyVisibleImageResultRange } = this;\n const { selectedResultIndex } = args;\n\n if (selectedResultIndex == null) {\n return;\n }\n\n if (\n fullyVisibleImageResultRange.firstIndex <= selectedResultIndex &&\n selectedResultIndex <= fullyVisibleImageResultRange.lastIndex\n ) {\n return;\n }\n\n const scrollPositionIfResultIndexIsCentered =\n selectedResultIndex * ResultImageSize - componentWidth / 2 - ResultImageSize / 2;\n // center the newly selected result on the page (within the bounds ofcourse)\n const newScrollPosition = this.getBoundedScrollPosition(scrollPositionIfResultIndexIsCentered);\n this.listScrollAmount = newScrollPosition;\n }\n}\n\ndeclare module '@glint/environment-ember-loose/registry' {\n export default interface Registry {\n 'Video::AdvancedVideoSearch::FoundSearchResults': typeof FoundSearchResults;\n }\n}\n","import { precompileTemplate } from \"@ember/template-compilation\";\nexport default precompileTemplate(\"{{! template-lint-disable no-inline-styles }}\\n{{!-- template-lint-disable no-pointer-down-event-binding --}}\\n\\n
    \\n \\n \\n
    \\n {{#if @startTime}}\\n
    \\n {{format-time-tz\\n @startTime\\n hour=\\\"numeric\\\"\\n minute=\\\"numeric\\\"\\n }}\\n
    \\n {{/if}}\\n {{#if @endTime}}\\n
    \\n {{format-time-tz\\n @endTime\\n hour=\\\"numeric\\\"\\n minute=\\\"numeric\\\"\\n }}\\n
    \\n {{/if}}\\n
    \\n {{#each this.orderedThumbnailUrlList as |thumbnailStream index|}}\\n
    \\n {{#each thumbnailStream as |thumbnailItem|}}\\n
    \\n \\n
    \\n {{/each}}\\n
    \\n {{/each}}\\n
    \\n {{!-- This value is null while events are loading, so show the loading bar on the timeline. --}}\\n {{#unless (eq @permanentEvents null)}}\\n
    \\n {{#each this.intervalsDisplay as |interval|}}\\n
    \\n {{/each}}\\n
    \\n
    \\n\\n {{#each (await this.permanentMarkersDisplay) as |marker index|}}\\n {{#unless marker.hideFromPrimaryStream}}\\n
    \\n {{#if marker.isCollation}}\\n {{marker.eventIds.length}}\\n {{else}}\\n \\n {{/if}}\\n
    \\n {{/unless}}\\n {{/each}}\\n {{else}}\\n
    \\n \\n
    \\n {{/unless}}\\n {{! the popover component for when hovering over event markers, with more details about the event/s}}\\n {{#let (await this.currentlyHoveredMarkerEvents) as |markerEventsObject|}}\\n {{#if markerEventsObject}}\\n
    \\n
    \\n
    \\n
    \\n {{#each markerEventsObject.events as |event|}}\\n
    \\n \\n
    \\n
    \\n
    {{event.deviceDescription}}
    \\n
    \\n {{format-time-tz\\n event.eventDate\\n hour=\\\"numeric\\\"\\n minute=\\\"numeric\\\"\\n }}\\n
    \\n
    \\n
    {{event.description}}
    \\n
    \\n {{#if event.thumbnail}}\\n
    \\n {{#if event.thumbnail.hasLoaded}}\\n {{event.thumbnail}}\\n {{else}}\\n \\n {{/if}}\\n
    \\n {{/if}}\\n
    \\n {{/each}}\\n
    \\n
    \\n
    \\n
    \\n {{/if}}\\n {{/let}}\\n
    \\n {{#if @expandedMode}}\\n
    \\n {{#each this.individualStreams as |stream index|}}\\n
    \\n {{#if stream.isSchedulePaused}}\\n \\n {{/if}}\\n
    {{stream.cameraDescription}}
    \\n
    \\n {{/each}}\\n {{#unless (eq this.pausedToolTipVisibleIndex null)}}\\n \\n {{tc this \\'localRecordingRulePaused\\'}}\\n \\n {{/unless}}\\n
    \\n
    \\n {{#each this.individualStreams as |stream index|}}\\n
    \\n
    \\n {{#each stream.intervalsDisplay as |interval|}}\\n
    \\n {{/each}}\\n
    \\n\\n
    \\n
    \\n {{#each (await stream.permanentMarkersDisplay) as |marker|}}\\n
    \\n
    \\n {{/each}}\\n
    \\n
    \\n {{/each}}\\n
    \\n {{/if}}\\n
    \\n {{#if @endTime}}\\n
    {{format-date-tz @endTime month=\\\"short\\\" day=\\\"numeric\\\" }}
    \\n {{/if}}\\n \\n \\n \\n
    \\n \\n \\n \\n

    \\n {{format-time-tz\\n this.tooltipTime\\n hour=\\\"numeric\\\"\\n minute=\\\"numeric\\\"\\n second=\\\"numeric\\\"\\n }}\\n

    \\n
    \\n
    \\n \\n
    \\n {{#if @avsDataObject}}\\n \\n {{/if}}\\n
    \",{ moduleName: \"customer-site/components/video/video-timeline/index.hbs\" })","/* import __COLOCATED_TEMPLATE__ from './index.hbs'; */\nimport Component from '@glimmer/component';\nimport { tracked } from '@glimmer/tracking';\nimport { areArraysSame } from '@adc/ember-utils/utils/array';\nimport { isDestroyed } from '@adc/ember-utils/utils/ember-helpers';\nimport { isBetween } from '@adc/ember-utils/utils/math';\nimport { computed, action, set, setProperties } from '@ember/object';\nimport { alias, reads } from '@ember/object/computed';\nimport { guidFor } from '@ember/object/internals';\nimport { debounce } from '@ember/runloop';\nimport { inject as service } from '@ember/service';\nimport { htmlSafe } from '@ember/template';\nimport { restartableTask } from 'ember-concurrency';\nimport { Motion, Restricted } from 'customer-site/enums/RecordingIntervalType';\nimport { TimelineClick, TimelineArrowForward, TimelineArrowBack } from 'customer-site/enums/TrackedEvent';\nimport { NUM_SECONDS_IN_MINUTE, NUM_SECONDS_IN_DAY, NUM_MILLISECONDS_IN_MINUTE } from 'customer-site/utils/datetime';\nimport { getIconForEvent } from 'customer-site/utils/video/general';\nimport { logEventConditionToWavefront, TIMELINE_TIME_UPDATE } from 'customer-site/utils/video/wavefront-stats';\nimport { POST } from '@adc/ajax/services/adc-ajax';\nimport { intlPath } from '@adc/i18n/path';\nimport { utcToZonedTime } from 'date-fns-tz';\nimport addMilliseconds from 'date-fns/addMilliseconds';\nimport addSeconds from 'date-fns/addSeconds';\nimport differenceInMilliseconds from 'date-fns/differenceInMilliseconds';\nimport differenceInSeconds from 'date-fns/differenceInSeconds';\nimport isAfter from 'date-fns/isAfter';\nimport isBefore from 'date-fns/isBefore';\nimport max from 'date-fns/max';\nimport min from 'date-fns/min';\nimport subSeconds from 'date-fns/subSeconds';\n\nimport './_style.scss';\nimport type { Registry as ServiceRegistry } from '@ember/service';\nimport type { SafeString } from '@ember/template';\nimport type { StreamUsage } from 'customer-site/enums/StreamUsage';\nimport type HistoryEvent from 'customer-site/models/activity/history-event';\nimport type Interval from 'customer-site/models/video/interval';\nimport type { AVSDataObject } from '../advanced-video-search/page/index';\nimport type {\n ScrubberThumbnailProperties,\n ScrubbedThumbnailUrls,\n IntervalsData,\n IntervalData\n} from '../video-player/playback-features/types';\nimport './_style.scss';\n\n// If event markers are less than this distance (timeline percentage) apart, they should be collated/combined into a numbered marker.\n// Currently set at 0.9 to represent points overlapping by 60% on a typical browser width (somewhat arbitrary).\nconst COLLATION_CLOSENESS_FACTOR = 0.9,\n // The maximum distance (timeline percentage) that the earliest point can be from the latest point in a numbered marker.\n // These values were set somewhat arbitrarily and can be modified based on user feedback.\n MAX_COLLATION_DISTANCE_FACTOR = 4,\n // The maximum amount of events allowed to be collated into an individual marker\n MAX_MARKER_SIZE = 25,\n // If the popover is computing the same event ids too quickly it can create a rapid/glitchy visual effect.\n // If this happens more than once in this many milliseconds or less we don't show the popover.\n // This can happen if the popover is appearing over the same mouse location as the same event in the event-sidebar.\n POPOVER_OVERCOMPUTE_CHECK_TIME_MS = 250,\n // When the triangle for the popover gets too close to the edge of the popover (less than this number of pixels) it looks weird, so this is used\n // to set a minimum distance that the triangle must be from the popover edge.\n POPOVER_SPACING_ADJUSTER = 20,\n // The margin-left css value of the event-info part of the popover when there are no spacing limitations\n DEFAULT_POPOVER_MARGIN_LEFT = -70,\n // Minimum time between thumbnail hover requests.\n DEFER_TIMEOUT_PERIOD_MS = 50,\n // Height to add to timeline for each individual stream.\n INDIVIDUAL_STREAM_HEIGHT = 16,\n // How tall the Advanced Video Search results pane is.\n AVS_SEARCH_RESULTS_HEIGHT = 126,\n // Base height for the video timeline component.\n NO_STREAMS_HEIGHT = 44;\n\ninterface VideoTimelineSignature {\n Args: {\n allStreamsIntervals: IntervalsData[] | null; // All the intervals for the devices\n areControlsEnabled: boolean;\n avsDataObject?: AVSDataObject;\n changeSelectedAvsResult: (newIndex: number) => void;\n currentTime?: Date;\n earliestTime: Date | null; // Earliest time with actual recordings.\n endTime: Date | null; // End time of the timeline interval.\n eventFilterFn: (\n eventId: number,\n deviceTypeFilterIds: number[],\n ovClassification: number,\n globalDeviceId: string\n ) => boolean;\n eventHover: (eventIds: string[]) => void; // Event for if when a marker event is hovered over\n expandedCameraIndex?: number;\n expandedMode: boolean;\n goToEvent: (event: HistoryEvent) => void;\n highlightedEventIds: string[]; // The list of all events that are currently being hovered over.\n individualThumbnailMode: boolean; // Determines if we should skip thumbnail precaching and load individual images on demand.\n latestTime: Date | null; // Latest time with actual recordings.\n lockTimelineBoundsToAvailableVideo: boolean;\n pauseVideo: () => void;\n permanentEvents: HistoryEvent[] | null;\n playerType?: StreamUsage;\n restartAvsSearch: () => void;\n scrubberThumbnailProperties?: ScrubberThumbnailProperties; // Object with number of minutes between thumbnails on timeline.\n scrubberThumbnailUrls: ScrubbedThumbnailUrls | null; // List of Base URLs for getting scrubber thumbnails.\n startTime: Date | null; // Start time of the timeline interval.\n timelineChangeDebounceTimeMs: number; // The time in milliseconds to debounce certain functions dealing with the timeline, including thumbnail requests to VideoRelay and retrieving event history.\n timelineNewTimeSet: (newTime: Date, trackedEventEnum: number) => void;\n timelineSelectionStart: () => void; // Event for if a new time is clicked\n timelineUpdate: (newTime: Date, shouldResumePlayback: boolean) => void; // Event for when a new time is set while being dragged on the timeline.\n };\n Element: HTMLDivElement;\n}\n\n// Primary marker represents the large icon/numbered markers, secondary markers are the small orange dots below the primary ones.\nenum MouseLocation {\n PrimaryMarker,\n SecondaryMarker,\n Popover,\n Other\n}\n\n// Info about events for the hovered marker\ntype HoveredMarkerEvents = {\n anchorSelector?: string;\n id?: number;\n events: {\n description: string;\n deviceDescription: string;\n eventDate: Date;\n eventId: string;\n thumbnail: ThumbnailImage | undefined;\n icon: string;\n }[];\n styleCss: SafeString;\n startPercent: number;\n};\n\n// Info about the currently hovered event\ntype HoverEventInfo = {\n highlightedEventIds: string[];\n time: Date;\n};\n\n// An individual interval (ie a motion interval)\ntype IntervalsDisplay = {\n type: string;\n styleCss: SafeString;\n};\n\n// Info about intervals/events for a stream\ntype IndividualStream = {\n intervalsDisplay: IntervalsDisplay[];\n permanentMarkersDisplay: MarkerObject[];\n cameraDescription: string;\n globalDeviceId?: string;\n isSchedulePaused?: boolean;\n selected: boolean;\n};\n\n// Markers on the timeline\ntype MarkerObject = {\n event: HistoryEvent;\n eventIds: Array;\n globalDeviceId: string | null;\n hideFromPrimaryStream?: boolean;\n icon: string;\n id?: number;\n isCollation: boolean;\n startPercent: number;\n start: string;\n styleCss: SafeString;\n type: string;\n};\n\n// Info about the scrubber request times\ntype ScrubberThumbnailRequestTimeParams = {\n numThumbnailsRequired?: number;\n startTimeRoundedByInterval?: Date;\n endTimeRoundedByInterval?: Date;\n};\n\n// The style data for the hover slider.\ntype TooltipStyling = {\n iconClass: SafeString;\n leftCss: SafeString;\n visibilityClass: string;\n};\n\ninterface ThumbnailImage extends HTMLImageElement {\n hasLoaded?: boolean;\n}\n\n/**\n * Returns if the event is a TouchEvent\n */\nfunction isTouchEvent(e: MouseEvent | TouchEvent): boolean {\n // need to check if TouchEvent is defined because it is not defined in some environments (firefox web for instance)\n return typeof TouchEvent !== 'undefined' && e instanceof TouchEvent;\n}\n\n/**\n * Updates the slider percentage to the percentage parameter passed in. Passed up an action if the action originated from an user event on this component (eg. dragging, clicking back/forward).\n *\n * @param percentage The slider percentage value.\n * @param [isFromUserEvent=false] True if this is being called from a user initiated event.\n */\nfunction updateSliderPercentage(this: TimeLineComponent, percentage: number, isFromUserEvent = false): void {\n // Set the internal slider percentage.\n this.sliderPercentage = percentage;\n\n if (isFromUserEvent) {\n // execute action\n this.args.timelineUpdate(getTimeFromSliderPercentage.call(this, this.sliderPercentage), false);\n }\n}\n\n/**\n * Returns the current time based on the the slider percentage on the timeline.\n *\n * @param [sliderPercentage]\n *\n * @returns The current time on the timeline represents.\n */\nfunction getTimeFromSliderPercentage(this: TimeLineComponent, sliderPercentage: number): Date {\n const { args, millisecondsInTimeline } = this,\n { startTime } = args;\n\n if (!startTime) {\n return new Date();\n }\n\n // Was a slider percentage NOT passed?\n if (sliderPercentage === undefined) {\n // Use start time.\n return startTime;\n }\n\n return addMilliseconds(startTime, Math.round((millisecondsInTimeline * sliderPercentage) / 100));\n}\n\n/**\n * Returns the slider percentage based on the parameter newTime.\n *\n * @param newTime The time which you want the slider percentage for.\n *\n * @returns The slider percentage from a range of 0 to 100.\n */\nfunction getSliderPercentageFromTime(this: TimeLineComponent, newTime: Date): number | undefined {\n const { args, millisecondsInTimeline } = this,\n { endTime } = args;\n\n if (!endTime) {\n return;\n }\n\n return ((millisecondsInTimeline - differenceInMilliseconds(endTime, newTime)) * 100) / millisecondsInTimeline;\n}\n\n/**\n * Since calculations are done based off of the left xOffset, we check if we are in an Rtl language, and if so,\n * we mirror the offset by subtracting it from 100.\n *\n * @param xOffset The distance the timeline srubber is from the left of the screen\n *\n * @returns The distance the scrubber is from the left or right of the screen, depending on Rtl\n */\nfunction getLocalizedPercent(this: TimeLineComponent, xOffset: number): number {\n return this.isRtl ? 100 - xOffset : xOffset;\n}\n\n/**\n * For placing things on the page with a \"left\" css value, we need to flip this to \"right\" while in RTL mode\n */\nfunction getRtlSideString(this: TimeLineComponent): string {\n return this.isRtl ? 'right:' : 'left:';\n}\n\n/**\n * Returns the slider percentage based on a user event\n *\n * @param e Event passed into the method\n * @param [onlyInside = false] Forcing the drag event work past the width of the component. Allows us to continue dragging past the timeline without it resetting to 0\n *\n * @returns -1 if onlyInside is set to true and the event originated from outside the container which indicates the event itself is invalid. Otherwise, it'll return the slider percentage from the user event\n */\nfunction getSliderPercentageFromEvent(this: TimeLineComponent, e: MouseEvent | TouchEvent, onlyInside = false): number {\n let x: number;\n\n if (isTouchEvent(e)) {\n x = (e as TouchEvent).touches[0].clientX + document.body.scrollLeft + document.documentElement.scrollLeft;\n } else {\n x = (e as MouseEvent).pageX;\n }\n\n if (!document) {\n return -1;\n }\n\n // Get the screen position of the timeline so we can determine where the mouse was clicked inside the slider.\n const sliderOffset = document\n .getElementById(guidFor(this))\n ?.querySelector('.timeline-wrapper')\n ?.getBoundingClientRect();\n\n if (!sliderOffset || (onlyInside && (x < sliderOffset.left || x > sliderOffset.left + sliderOffset.width))) {\n return -1;\n }\n\n // Get x coordinate relative to the slider.\n x -= sliderOffset.left;\n\n // Turn the coordinate into a percentage.\n x = (x / sliderOffset.width) * 100;\n\n x = getLocalizedPercent.call(this, x);\n\n // Don't allow values less than 0 or more than 100.\n return Math.min(Math.max(x, 0), 100);\n}\n\n/**\n * Processes the touch event passed in by the user. Does nothing if the event originated from outside the container.\n *\n * @param e The mouse or touch event\n */\nfunction processPressEvent(this: TimeLineComponent, e: MouseEvent | TouchEvent): void {\n // Stop event propagation.\n // Note: Not doing this causes the slider to be \"HTML draggable\" and can hinder the slider handle from moving properly.\n\n if (!isTouchEvent(e)) {\n e.preventDefault();\n }\n\n e.stopPropagation();\n e.stopImmediatePropagation();\n\n if (!this.args.areControlsEnabled) {\n return;\n }\n\n // Remove the event listeners.\n removeTimelineDomListeners.call(this);\n\n const offset = getSliderPercentageFromEvent.call(this, e, true);\n\n // If the event is invalid, return immediately\n if (offset < 0) {\n return;\n }\n\n set(this, 'isMouseDown', true);\n\n // Trigger action.\n this.args.timelineSelectionStart();\n\n // Update the slider percentage to where they clicked.\n updateSliderPercentage.call(this, offset, true);\n\n const moveListener = isTouchEvent(e) ? 'touchmove' : 'mousemove',\n upListener = isTouchEvent(e) ? 'touchend' : 'mouseup';\n\n // Add listeners for drag events, mouse events and touch. (Cache them so we can remove them later).\n set(this, 'moveListener', this.dom.addListener(this, window.document.body, moveListener, mouseMove.bind(this)));\n set(this, 'upListener', this.dom.addListener(this, window.document.body, upListener, mouseUp.bind(this)));\n}\n\n/**\n * Processes the mouse enter event passed in by the user\n */\nfunction processHoverEvent(this: TimeLineComponent): void {\n if (!this.args.areControlsEnabled) {\n return;\n }\n\n // Remove the event listeners.\n removeTimelineDomListeners.call(this);\n\n set(this, 'moveListener', this.dom.addListener(this, window.document.body, 'mousemove', mouseMoveHover.bind(this)));\n}\n\n/**\n * Handler for mouseUp\n */\nfunction mouseUp(this: TimeLineComponent): void {\n const { currentTime, timelineNewTimeSet } = this.args;\n\n // Disable dragging on mouse move.\n setProperties(this, {\n isDragging: false,\n isMouseDown: false\n });\n\n // Set the new percentage and trigger the value-change action if defined.\n updateSliderPercentage.call(this, this.sliderPercentage, true);\n\n // Remove the event listeners.\n removeTimelineDomListeners.call(this);\n\n const action = timelineNewTimeSet;\n this.stats.logEvent(TimelineClick);\n\n if (action && currentTime) {\n // Update the app that the time change is complete.\n action(currentTime, TimelineClick);\n }\n\n if (this.mouseIn) {\n set(this, 'tooltipLocation', this.sliderPercentage);\n processHoverEvent.call(this);\n }\n}\n\n/**\n * Handler for mouseMove (eg. dragging)\n */\nfunction mouseMove(this: TimeLineComponent, e: MouseEvent): void {\n if (!this.args.areControlsEnabled) {\n return;\n }\n\n // Tell the component we are dragging.\n set(this, 'isDragging', true);\n\n e.preventDefault();\n\n // Set the new percentage and trigger the value-change action if defined.\n updateSliderPercentage.call(this, getSliderPercentageFromEvent.call(this, e), true);\n}\n\n/**\n * Handler for mouseMoveHover (eg. hovering without dragging)\n */\nfunction mouseMoveHover(this: TimeLineComponent, e: MouseEvent): void {\n if (!this.args.areControlsEnabled) {\n return;\n }\n\n set(this, 'tooltipLocation', getSliderPercentageFromEvent.call(this, e));\n\n if (!this.args.expandedMode) {\n // This prevents spamming image requests when rapidly scrubbing the timeline.\n // Do not copy this deprecated usage. If you see this, please convert to ember-lifeline debounceTask.\n // eslint-disable-next-line ember/no-runloop\n debounce(this, loadScrubberThumbnail, 0, DEFER_TIMEOUT_PERIOD_MS);\n }\n}\n\n/**\n * Handler for mouseMoveHoverForStream (eg. hovering without dragging)\n * This is used by the expanded version only.\n */\nfunction mouseMoveHoverForStream(this: TimeLineComponent, e: MouseEvent) {\n const { hoveredStreamIndex } = this;\n\n if (!this.args.areControlsEnabled || hoveredStreamIndex == null) {\n return;\n }\n\n set(this, 'tooltipLocation', getSliderPercentageFromEvent.call(this, e));\n\n // Allow the first trigger to execute immediately, but force subsequent calls to wait.\n // Do not copy this deprecated usage. If you see this, please convert to ember-lifeline debounceTask.\n // eslint-disable-next-line ember/no-runloop\n debounce(this, loadScrubberThumbnail, hoveredStreamIndex, DEFER_TIMEOUT_PERIOD_MS);\n}\n\n/**\n * Remove all dom listeners that are on the timeline.\n */\nfunction removeTimelineDomListeners(this: TimeLineComponent): void {\n this.moveListener && this.dom.removeListener(this, this.moveListener);\n this.upListener && this.dom.removeListener(this, this.upListener);\n}\n\n/**\n * Get the millisecond value for used as a display marker for edge of an interval.\n * Calculated given video and interval times relative to known start time.\n */\nfunction getIntervalEdge(this: TimeLineComponent, videoTime: Date, intervalTime: Date, isStartTime: boolean): number {\n const { millisecondsInTimeline, args } = this,\n { startTime } = args,\n fnMinOrMax = isStartTime ? max : min,\n fnResults = fnMinOrMax([videoTime, intervalTime]),\n intervalPercentage = (differenceInMilliseconds(fnResults, startTime || 0) / millisecondsInTimeline) * 100;\n\n return intervalPercentage;\n}\n\n/**\n * Display the thumbnail image on the scrubber based on the hover time.\n *\n * @param streamIndex Identifies which stream to request a thumbnail for.\n */\nfunction loadScrubberThumbnail(this: TimeLineComponent, streamIndex: number): void {\n // TODO: This ignore is an existing deprecation that must be refactored, do not copy this usage\n // eslint-disable-next-line @adc/ember/no-is-destroyed\n if (this.isDestroyed || streamIndex === null) {\n return;\n }\n\n // Hide and adjust all existing thumbnails shown to the user.\n hideScrubberThumbnails.call(this);\n const { orderedThumbnailUrlList } = this,\n currentThumbnailIndex = getCurrentThumbnailIndex.call(this, streamIndex),\n selectedScrubberThumbnail = `scrubber-thumbnail-${streamIndex}-${currentThumbnailIndex}`,\n hoveredImages = document.getElementsByClassName(\n selectedScrubberThumbnail\n ) as HTMLCollectionOf;\n\n // If nothing was found, then don't do anything.\n if (!hoveredImages?.length || currentThumbnailIndex == null) {\n return;\n }\n\n const image = hoveredImages[0],\n imageUrl = orderedThumbnailUrlList?.[streamIndex]?.[currentThumbnailIndex]?.url;\n\n // We need access to the URL and the image element to be able to load it.\n if (!imageUrl || !image) {\n return;\n }\n\n // Set the URL to load the image if we have not already done so.\n if (!image.src) {\n this.thumbnailLoadListener = () =>\n displayScrubberThumbnail.call(this, image, currentThumbnailIndex, streamIndex);\n\n // Prepare to display the image once it has fully loaded.\n image.addEventListener('load', this.thumbnailLoadListener);\n image.setAttribute('src', imageUrl);\n }\n // If image is still loading, just wait for the original display call to trigger.\n // If already fully loaded, make another call to display it.\n // The second check ensures that we will display nothing in gaps or if a faulty/empty image is retrieved.\n else if (image.complete && image.naturalWidth !== 0) {\n displayScrubberThumbnail.call(this, image, currentThumbnailIndex, streamIndex);\n }\n}\n\n/**\n * Actually render the hovered thumbnail.\n *\n * @param image The image element triggering the event.\n * @param minuteIndex Index of the timeline segment this image corresponds to.\n * @param streamIndex Identifies which stream to request a thumbnail for.\n */\nfunction displayScrubberThumbnail(\n this: TimeLineComponent,\n image: HTMLImageElement,\n minuteIndex: number,\n streamIndex: number\n): void {\n // TODO: This ignore is an existing deprecation that must be refactored, do not copy this usage\n // eslint-disable-next-line @adc/ember/no-is-destroyed\n if (this.isDestroyed) {\n return;\n }\n\n const { hoveredStreamIndex, isMouseDown, mouseIn } = this,\n currentThumbnailIndex = getCurrentThumbnailIndex.call(this, streamIndex);\n\n // We are no longer hovered on this image or the image is empty, so leave it hidden.\n if (currentThumbnailIndex !== minuteIndex || hoveredStreamIndex !== streamIndex || image.naturalWidth === 0) {\n return;\n }\n\n const display = mouseIn && !isMouseDown ? 'inherit' : 'none';\n image.setAttribute('style', `display: ${display};`);\n image.classList.remove('hidden');\n set(this, 'hoveredImage', image);\n}\n\n/**\n * Hide the hovered thumbnail.\n */\nfunction hideScrubberThumbnails(this: TimeLineComponent): void {\n // Get all the scrubber thumbnails.\n const { hoveredImage } = this;\n\n if (!hoveredImage) {\n return;\n }\n\n // Remove the style so it's positioned to its default location.\n hoveredImage.setAttribute('style', '');\n\n // Remove any on load function.\n hoveredImage.onload = null;\n this.thumbnailLoadListener && hoveredImage.removeEventListener('load', this.thumbnailLoadListener);\n\n // Add the hidden class if it's not already there.\n if (!hoveredImage.classList.contains('hidden')) {\n hoveredImage.classList.add('hidden');\n }\n\n set(this, 'hoveredImage', null);\n}\n\n/**\n * Converts an array of intervals to an array that is formatted to be displayed in the template.\n *\n * @param intervalsGroup Array of interval data for the device.\n */\nfunction convertIntervalsArrayToIntervalsDisplayArray(\n this: TimeLineComponent,\n intervalsGroup: Interval[]\n): IntervalsDisplay[] {\n const { startTime: timelineStartTime, endTime: timelineEndTime, avsDataObject } = this.args,\n videoContinuousIntervalType = 'line video-available',\n // avs motion intervals are displayed a different color from other motion events (blue)\n videoMotionIntervalType = 'line video-motion' + (avsDataObject ? ' avs' : ''),\n videoPauseType = 'line video-pause',\n videoRestrictedType = 'line video-restricted';\n\n if (!intervalsGroup || !timelineStartTime || !timelineEndTime) {\n // Nothing to display.\n return [];\n }\n\n return intervalsGroup\n .map(({ startTime, endTime, toggledBy, type }) => {\n // Is this interval outside the current range?\n if (isAfter(startTime, timelineEndTime) || isBefore(endTime, timelineStartTime)) {\n // Skip it.\n return undefined;\n }\n\n const startPercent = getIntervalEdge.call(this, timelineStartTime, startTime, true),\n sideString = getRtlSideString.call(this),\n widthPercent = getIntervalEdge.call(this, timelineEndTime, endTime, false) - startPercent;\n\n let typeString;\n if (toggledBy) {\n typeString = videoPauseType;\n } else if (type === Motion) {\n typeString = videoMotionIntervalType;\n } else if (type === Restricted) {\n typeString = videoRestrictedType;\n } else {\n typeString = videoContinuousIntervalType;\n }\n\n return {\n type: typeString,\n styleCss: htmlSafe(`${sideString} ${startPercent}%; width:${widthPercent}%`)\n };\n })\n .compact();\n}\n\n/**\n * Creates a Marker display object from the parameters passed in\n *\n * @param leftPercent how far from the left in the timeline it should be displayed, as a percentage\n * @param eventIds an array of the event id's associated\n * @param event the event object. Note this is only used for getting the icon and can be passed as null if the icon param is not needed (ie is a collated marker)\n * @param globalDeviceId the global device id for the camera\n * @param sideString normally equal to 'left:', but equal to 'right:' when in RTL mode\n */\nfunction createMarkerObject(\n leftPercent: number,\n eventIds: Array,\n event: HistoryEvent,\n globalDeviceId: string | null,\n sideString: string\n): MarkerObject {\n return {\n startPercent: leftPercent,\n start: leftPercent + '%',\n styleCss: htmlSafe(`${sideString} ${leftPercent}%`),\n icon: getIconForEvent(event),\n globalDeviceId,\n event,\n eventIds: eventIds,\n isCollation: eventIds.length > 1,\n type: globalDeviceId ? 'device-event' : 'system-event'\n };\n}\n\n/**\n * Returns a collated/numbered marker representing all of the markers\n * (Note that the marker data is expected to be passed in sorted by datetime ascending)\n *\n * @param markersToCollate the array of markers to combine into one\n * @param sideString normally equal to 'left:', but equal to 'right:' when in RTL mode\n *\n * @returns {Object}\n */\nfunction createCollatedMarker(markersToCollate: MarkerObject[], sideString: string): MarkerObject | null {\n if (!markersToCollate || !markersToCollate.length) {\n return null;\n }\n\n const earliestMarker = markersToCollate[0],\n lastMarker = markersToCollate[markersToCollate.length - 1],\n earliestStartVal = earliestMarker.startPercent,\n latestStartVal = lastMarker.startPercent,\n avgStartVal = (earliestStartVal + latestStartVal) / 2;\n\n const eventIds = markersToCollate.map(function (marker) {\n return marker.eventIds.length ? marker.eventIds[0] : null;\n });\n\n // Passing in the earliest marker's event for the event variable so that when the marker is clicked it will navigate to that one.\n return createMarkerObject(avgStartVal, eventIds, earliestMarker.event, null, sideString);\n}\n\n/**\n * Takes an array of the markers and returns the same list with collated/numbered markers added to it.\n *\n * @param markers the initial array of markers\n * @param sideString normally equal to 'left:', but equal to 'right:' when in RTL mode\n */\nfunction getMarkersCollated(markers: MarkerObject[], sideString: string): MarkerObject[] {\n let markersToCollate: MarkerObject[] = [];\n const collationPointsData: MarkerObject[][] = [];\n\n // The point of this for loop is to populate collationPointsData with markers that need to be collated/combined to be numbered markers.\n for (let i = 1; i < markers.length; i++) {\n const currentMarker = markers[i];\n const { startPercent } = currentMarker;\n\n // The current marker and the previous marker are close enough on the screen that they should be collated into one marker.\n const closeToPreviousMarker = startPercent < markers[i - 1].startPercent + COLLATION_CLOSENESS_FACTOR;\n\n // If this marker is close to the previous marker,\n // and the marker size won't get larger than the MAX_MARKER_SIZE,\n // and the distance to the first collated marker in the set isn't too large, lets collate this.\n const shouldCollateThisMarker =\n closeToPreviousMarker &&\n markersToCollate.length < MAX_MARKER_SIZE &&\n !(\n markersToCollate.length &&\n markersToCollate[0].startPercent + MAX_COLLATION_DISTANCE_FACTOR < startPercent\n );\n\n if (shouldCollateThisMarker) {\n // We found the current marker is close to the previous marker, so we need to set the previous marker to be collated also.\n if (!markersToCollate.length) {\n const previousMarker = markers[i - 1];\n previousMarker.hideFromPrimaryStream = true;\n markersToCollate.push(previousMarker);\n }\n\n // Hide from the primary stream because it will only show as a numbered/collated event marker.\n currentMarker.hideFromPrimaryStream = true;\n markersToCollate.push(currentMarker);\n } else if (markersToCollate.length) {\n // The previous marker was the last one in the set that needs to be collated.\n collationPointsData.push(markersToCollate);\n // Resetting array.\n markersToCollate = [];\n }\n }\n\n // If the last marker in the array needs to be collated, lets that marker set to collationPointsData\n if (markersToCollate.length) {\n collationPointsData.push(markersToCollate);\n }\n\n // Creating the numbered markers based and adding them to the list of markers.\n collationPointsData.forEach((collationPointData) => {\n const newMarker = createCollatedMarker(collationPointData, sideString);\n\n if (newMarker) {\n markers.push(newMarker);\n }\n });\n\n // Sorting these so that the ones on the right always overlap the left.\n markers.sort((a, b) => (a.startPercent > b.startPercent ? 1 : -1));\n\n // Giving all of the markers an id value from their order.\n markers.forEach(function (marker, index) {\n marker.id = index;\n });\n\n return markers;\n}\n\n/**\n * Will retrieve an Image object corresponding to the event from the cache if possible.\n * Otherwise it'll create and cache a new Image object using thumbnail url\n *\n * @param eventId the id of the event, used as the key for the image in the cache\n * @param thumbnailUrl the url of for the image source\n */\nfunction getThumbnailImage(this: TimeLineComponent, eventId: number, thumbnailUrl: string): ThumbnailImage | undefined {\n const { thumbnailCache, intl } = this;\n\n if (thumbnailCache?.has(eventId)) {\n return thumbnailCache.get(eventId);\n }\n\n const thumbnailImage = new Image() as ThumbnailImage;\n thumbnailCache?.set(eventId, thumbnailImage);\n\n setProperties(thumbnailImage, {\n onload: () => {\n set(thumbnailImage, 'hasLoaded', true);\n },\n alt: intl.tc(this, 'eventThumbnail'),\n className: 'event-thumbnail',\n src: thumbnailUrl\n });\n\n return thumbnailImage;\n}\n\n/**\n * Updates time, loads event history, and resets the thumbnail cache\n */\nfunction updateTime(this: TimeLineComponent, newTime: Date, wavefrontAction: number): void {\n // Update the app that the time change is complete\n this.args.timelineNewTimeSet(newTime, wavefrontAction);\n}\n\n/**\n * Returns the current thumbnail index that should be displayed.\n * Correctly select the hovered image based on hover time relative to start time.\n * It selects the closest thumbnail to the selected time.\n * For example, in Day Mode, it'll show thumbnail at index 0 from 00:00 to 00:29,\n * index 1 from 00:30-01:29, ..., and the last index will cover 22:30-24:00.\n */\nfunction getCurrentThumbnailIndex(this: TimeLineComponent, streamIndex: number): number | undefined {\n const { tooltipTime, thumbnailMinutesIncrement } = this,\n { startTimeRoundedByInterval } = this.scrubberThumbnailsRequestTimeParameters(streamIndex);\n\n if (!thumbnailMinutesIncrement?.[streamIndex] || !startTimeRoundedByInterval) {\n return;\n }\n\n // Select the closest thumbnail to the selected hover time relative to the rounded start time.\n return Math.round(\n differenceInMilliseconds(tooltipTime, startTimeRoundedByInterval) /\n (thumbnailMinutesIncrement[streamIndex] * NUM_MILLISECONDS_IN_MINUTE)\n );\n}\n\n/*\n * Returns the full url for retrieving a scrubber thumbnail\n */\nexport function getFullUrlForScrubberThumbnail(\n envSettings: ServiceRegistry['env-settings'],\n scrubberThumbnailUrl: string,\n startTime: Date,\n interval = 1\n): string {\n const formattedStartTimeUtc = startTime.toISOString();\n\n // The test environment uses a base64 data URI format.\n return envSettings.isTestEnvironment()\n ? scrubberThumbnailUrl\n : `${scrubberThumbnailUrl}&start=${formattedStartTimeUtc}&interval=${interval}`;\n}\n\n/**\n * @classdesc\n * Displays a video timeline which can be navigated.\n */\n@intlPath({ path: 'video/video-timeline' })\nexport default class TimeLineComponent extends Component {\n @service declare locale: ServiceRegistry['locale'];\n @service declare ajax: ServiceRegistry['ajax'];\n @service declare identityManager: ServiceRegistry['identity'];\n @service declare dom: ServiceRegistry['dom'];\n @service declare stats: ServiceRegistry['stats'];\n @service declare envSettings: ServiceRegistry['env-settings'];\n @service declare intl: ServiceRegistry['adc-intl'];\n\n /**\n * The number of seconds it'll take for the slider to animate from one position to another when the timeline is clicked.\n */\n sliderTransitionTime = 0.15;\n\n /**\n * Is the timeline currently being dragged.\n */\n isDragging = false;\n\n /**\n * Does the user currently have the mouse held down.\n */\n isMouseDown = false;\n\n /**\n * Indicates the the interface is right to left.\n */\n @alias('locale.isRtl')\n declare isRtl: boolean;\n\n /**\n * Component rendered on a Visual Verification page\n */\n @reads('identityManager.identityModel.isVisualVerification')\n declare isOperatorSession: boolean;\n\n /**\n * The list of thumbnail URLs for displaying on the timeline (collapsed-stream mode only).\n */\n @tracked thumbnailUrlList: ScrubbedThumbnailUrls[] | null = null;\n\n /**\n * Tracks stream which triggered a hover event. Necessary to allow expanded scrubbing.\n */\n hoveredStreamIndex: number | null = null;\n\n /**\n * The image element that is currently being hovered over.\n */\n hoveredImage: HTMLElement | null = null;\n\n /**\n * The listener for the mouse move event.\n */\n moveListener: string | null = null;\n\n /**\n * Listener for the mouse up event.\n */\n upListener: string | null = null;\n\n /**\n * Listener which handles hover events for thumbnail scrubbing in expanded mode.\n */\n scrubberMoveListener: string | null = null;\n\n /**\n * Listener which triggers to display scrubber thumbnails\n */\n thumbnailLoadListener: (() => void) | null = null;\n\n /**\n * A number representing the current location of the user's mouse.\n */\n @tracked\n mouseLocation = MouseLocation.Other;\n\n /**\n * If the mouse is currently hovering over the timeline.\n */\n mouseIn = false;\n\n /**\n * The amount of pixels to the left that the tooltip is\n */\n tooltipLocation = 0;\n\n /**\n * A map with keys of event ids mapping to values of images\n */\n thumbnailCache: Map | null = null;\n\n /**\n * Contains information about the previous hover event. (This is for comparing to the current values when currentlyHoveredMarkerEvents is re-computed)\n */\n previousHoverEventInfo: HoverEventInfo | null = null;\n\n /**\n * The event id of the highlighted popover event, if one exists. This is for if a user mouses over a specific event inside of a popover.\n */\n @tracked\n highlightedPopoverEventId: string | null = null;\n\n /**\n * The task currently being performed to retrieve thumbnail URLs.\n */\n thumbnailUrlTaskInfo = null;\n\n /**\n * The css style property for the events-info div. We use this for adjusting its margins to fit better inside of the page (depending on location/size)\n */\n @tracked\n eventInfoStyle = '';\n\n /**\n * The visibility and index of the paused tooltip.\n * Null if hidden.\n */\n @tracked\n pausedToolTipVisibleIndex: number | null = null;\n\n /**\n * The percentage of the location of the slider from the left.\n */\n @tracked\n sliderPercentage = 0;\n\n /**\n * Number of seconds for the timeline's interval.\n */\n @computed('args.{endTime,startTime}')\n get timeInterval(): number {\n return differenceInSeconds(this.args.endTime || 0, this.args.startTime || 0) + 1;\n }\n\n /**\n * The time beside the hover slider.\n */\n @computed('tooltipLocation')\n get tooltipTime(): Date {\n return getTimeFromSliderPercentage.call(this, this.tooltipLocation);\n }\n\n /**\n * The time selected by the slider-thumb.\n */\n @computed('sliderPercentage')\n get selectedTime(): Date {\n return getTimeFromSliderPercentage.call(this, this.sliderPercentage);\n }\n\n /**\n * The amount of milliseconds difference between the selected start time and the selected end time\n */\n @computed('args.{endTime,startTime}')\n get millisecondsInTimeline(): number {\n const { startTime, endTime } = this.args;\n\n return differenceInMilliseconds(endTime || 0, startTime || 0);\n }\n\n /**\n * The class name binding for css to handle expanded / collapsed timeline modes.\n */\n @computed('args.expandedMode')\n get streamTypeCss(): string {\n return this.args.expandedMode ? 'expanded-mode' : 'collapsed-mode';\n }\n\n /**\n * The number of active streams on the timeline.\n */\n @computed('args.scrubberThumbnailUrls')\n get numberOfStreams(): number {\n return (this.args.scrubberThumbnailUrls || []).length;\n }\n\n /**\n * Should we make a preliminary request to VideoRelay to prepare thumbnails before retrieving\n * any individual thumbnails for the scrubber?\n */\n @computed('args.{individualThumbnailMode,scrubberThumbnailUrls}')\n get preloadScrubberThumbnails(): boolean | undefined {\n // The test environment uses a base64 data URI format, so it will not contain the 'SdCard' string.\n return (\n this.envSettings.isTestEnvironment() ||\n (this.args.scrubberThumbnailUrls?.[0]?.url?.includes('SdCard') && !this.args.individualThumbnailMode)\n );\n }\n\n /**\n * A mapping between event id's and their corresponding marker id's.\n */\n @computed('allHoveredMarkerEvents')\n get eventToMarkerMapping(): Promise> {\n return (async () => {\n const allHoveredMarkerEvents = await this.allHoveredMarkerEvents,\n eventToMarkerMapping = new Map();\n\n if (!allHoveredMarkerEvents.length) {\n return eventToMarkerMapping;\n }\n\n allHoveredMarkerEvents.forEach((marker) => {\n marker.events.forEach((event) => {\n eventToMarkerMapping.set(event.eventId, marker.id);\n });\n });\n\n return eventToMarkerMapping;\n })();\n }\n\n /**\n * Returns the id value for the marker currently being highlighted/hovered, if any.\n */\n @computed('eventToMarkerMapping', 'args.highlightedEventIds')\n get highlightedMarkerId(): Promise {\n return (async () => {\n const { highlightedEventIds } = this.args,\n eventToMarkerMapping = await this.eventToMarkerMapping;\n\n if (!highlightedEventIds || !highlightedEventIds.length) {\n return undefined;\n }\n\n // Can just retrieve the one that matches the first highlighted event id because there is no use case where multiple markers will be highlighted at once.\n return eventToMarkerMapping.get(highlightedEventIds[0]);\n })();\n }\n\n /**\n * Retreives the marker events that match the list of highlighted events in order to display the marker event popover.\n */\n @computed('args.highlightedEventIds', 'highlightedMarkerId', 'allHoveredMarkerEvents')\n get currentlyHoveredMarkerEvents(): Promise {\n return (async () => {\n const { args, mouseLocation, previousHoverEventInfo } = this,\n { highlightedEventIds } = args,\n highlightedMarkerId = await this.highlightedMarkerId,\n allHoveredMarkerEvents = await this.allHoveredMarkerEvents,\n markerEventsObject = allHoveredMarkerEvents.findBy('id', highlightedMarkerId);\n\n if (!markerEventsObject || !highlightedEventIds) {\n return undefined;\n }\n\n const markerEvents = markerEventsObject.events;\n\n if (\n previousHoverEventInfo &&\n areArraysSame(previousHoverEventInfo.highlightedEventIds, highlightedEventIds)\n ) {\n // If the previously highlighted event ids matches the current highlighted event ids and it happened very recently, this is likely the bug in VID-39344.\n // That bug is caused when the popover goes on top of the event sidebar which causes the event to become un-hovered, which then causes the popover to disappear,\n // which then causes the event to become hovered again. An infinite loop. Let's just not show the popover to avoid this infinite loop.\n if (new Date().getTime() - previousHoverEventInfo.time.getTime() < POPOVER_OVERCOMPUTE_CHECK_TIME_MS) {\n return undefined;\n }\n }\n\n // Do not copy this deprecated usage. If you see this, please fix it\n // eslint-disable-next-line ember/no-side-effects\n set(this, 'previousHoverEventInfo', {\n highlightedEventIds,\n time: new Date()\n });\n\n const primaryMarkerSelector = `#marker-${markerEventsObject.id}`,\n secondaryMarkerSelector = `#marker-stream-${highlightedEventIds.firstObject}`;\n\n // The anchor is on the secondary/orange markers EXCEPT for when the user is hovering over the primary marker, or the secondary marker doesnt exist for this event.\n // The secondary marker won't exist for an event if, for instance, we've highlighted over an event in the sidebar which isn't an event from a device\n // that is one of the selected streams.\n const anchorSelector =\n mouseLocation !== MouseLocation.PrimaryMarker && document.querySelector(secondaryMarkerSelector)\n ? secondaryMarkerSelector\n : primaryMarkerSelector;\n\n // If we're retrieving all of the marker events unfiltered.\n if (markerEvents.length === highlightedEventIds.length) {\n return {\n ...markerEventsObject,\n anchorSelector\n };\n }\n\n const filteredMarkerEvents = markerEvents.filter((event) => {\n return highlightedEventIds.includes(event.eventId);\n });\n\n return {\n ...markerEventsObject,\n events: filteredMarkerEvents,\n anchorSelector\n };\n })();\n }\n\n /**\n * Returns an array with the marker event data for all of the markers being displayed.\n *\n * @type {Array}\n */\n @computed('args.permanentEvents', 'permanentMarkersDisplay')\n get allHoveredMarkerEvents(): Promise {\n return (async () => {\n const { permanentEvents } = this.args,\n permanentMarkersDisplay = await this.permanentMarkersDisplay;\n const allHoveredMarkerEvents: HoveredMarkerEvents[] = [];\n\n permanentMarkersDisplay.forEach((marker) => {\n const { eventIds, hideFromPrimaryStream } = marker;\n\n if (hideFromPrimaryStream) {\n return;\n }\n\n const matchingEvents = permanentEvents?.filter(({ id }) => eventIds.includes(id));\n\n const markerEventData = matchingEvents?.map((event) => {\n const { eventDate, deviceDescription, description, thumbnailUrl, correlatedEventId } = event,\n thumbnail = thumbnailUrl\n ? getThumbnailImage.call(this, correlatedEventId, thumbnailUrl)\n : undefined;\n\n return {\n description,\n deviceDescription,\n eventDate,\n eventId: event.id,\n thumbnail,\n icon: getIconForEvent(event)\n };\n });\n\n allHoveredMarkerEvents.push({\n id: marker.id,\n events: markerEventData || [],\n styleCss: marker.styleCss,\n startPercent: marker.startPercent\n });\n });\n\n return allHoveredMarkerEvents;\n })();\n }\n\n /**\n * Retrieves intervals and events data for individual streams (used when expandedMode=true)\n */\n @computed(\n 'args.{allStreamsIntervals,avsDataObject,expandedCameraIndex,permanentMarkersCollated}',\n 'args.allStreamsIntervals.@each.{intervals,isSchedulePaused}',\n 'permanentMarkersDisplay'\n )\n get individualStreams(): IndividualStream[] | undefined {\n const { allStreamsIntervals, avsDataObject, expandedCameraIndex } = this.args;\n let { permanentMarkersDisplay } = this;\n\n if (!allStreamsIntervals) {\n return undefined;\n }\n\n const streams = allStreamsIntervals\n .sortBy('cameraItem.viewIndex')\n .map((stream, index) => {\n const { cameraItem, intervals, isSchedulePaused } = stream,\n cameraModel = cameraItem?.model;\n\n // Omit this stream.\n if (!cameraModel) {\n return undefined;\n }\n\n // If we are in an AVS context, lets display the AVS search results in the timeline rather than the regular intervals\n const intervalArrayToConvert = avsDataObject?.searchResults ?? intervals,\n intervalsDisplay = convertIntervalsArrayToIntervalsDisplayArray.call(this, intervalArrayToConvert);\n\n permanentMarkersDisplay = permanentMarkersDisplay?.filter(\n ({ globalDeviceId }) => globalDeviceId === cameraModel.id\n );\n\n return {\n intervalsDisplay,\n permanentMarkersDisplay,\n cameraDescription: cameraModel.description,\n globalDeviceId: cameraModel.globalDeviceId,\n isSchedulePaused,\n selected: [undefined, index].indexOf(expandedCameraIndex) !== -1\n };\n })\n .compact();\n\n return streams;\n }\n\n /**\n * The number of individual streams being rendered in the timeline.\n */\n @computed('args.expandedMode', 'individualStreams.[]')\n get numIndividualStreams(): number {\n return this.args.expandedMode ? this.individualStreams?.length ?? 0 : 0;\n }\n\n /**\n * The display data to draw on the timeline depicting the recording intervals in the footage.\n */\n @computed('args.{allStreamsIntervals,allStreamsIntervals.@each.intervals,avsDataObject,expandedMode}')\n get intervalsDisplay(): IntervalsDisplay[] {\n const { allStreamsIntervals, avsDataObject, expandedMode } = this.args,\n motionIntervals: IntervalData[] = [],\n videoIntervals: IntervalData[] = [],\n restrictedIntervals: IntervalData[] = [];\n\n // If we're on expanded mode, this display isn't used (the intervals are displayed on the individual stream)\n if (expandedMode || !allStreamsIntervals) {\n return [];\n }\n\n // If we are in an AVS context, lets display the AVS search results in the timeline rather than the regular intervals\n if (avsDataObject && avsDataObject.searchResults) {\n return convertIntervalsArrayToIntervalsDisplayArray.call(this, avsDataObject.searchResults);\n }\n\n let allIntervals;\n\n if (allStreamsIntervals.length > 1) {\n // intervalsDisplay in expanded mode is used for the collapsed display only. For this display, we basically create an array of intervals which\n // are in the order of restricted then video then motion. This causes motion intervals to take priority over video intervals by being displayed on top of\n // them. Or in other words, if at 1pm one stream is in a motion event, and one stream is in a regular video section, the collapsed display timeline will\n // display 1pm as being a motion period.\n allStreamsIntervals.forEach((stream) => {\n if (!stream.intervals) {\n return;\n }\n\n stream.intervals.forEach((interval) => {\n switch (interval.type) {\n case Motion:\n motionIntervals.push(interval);\n break;\n case Restricted:\n restrictedIntervals.push(interval);\n break;\n default:\n videoIntervals.push(interval);\n break;\n }\n });\n });\n\n allIntervals = restrictedIntervals.concat(videoIntervals, motionIntervals);\n } else {\n allIntervals = allStreamsIntervals[0].intervals;\n }\n\n // When intervals is invalid or missing, generating the display array will return an empty array\n return convertIntervalsArrayToIntervalsDisplayArray.call(this, allIntervals);\n }\n\n /**\n * The permanent markers to be displayed on the timeline.\n */\n @computed('args.{endTime,eventFilterFn,permanentEvents,startTime}')\n get permanentMarkersDisplay(): MarkerObject[] {\n const { args, timeInterval } = this,\n { endTime, eventFilterFn, permanentEvents, startTime } = args;\n\n if (!permanentEvents || !startTime || !endTime) {\n return [];\n }\n\n const filteredEvents = permanentEvents.filter(\n ({ eventDate, eventType, deviceTypeFilter, ovClassification, globalDeviceId }) => {\n // Filter unnecessary events out before adding it to a list.\n return (\n isBefore(eventDate, endTime) &&\n isAfter(eventDate, startTime) &&\n eventFilterFn(eventType, deviceTypeFilter, ovClassification, globalDeviceId)\n );\n }\n ),\n sideString = getRtlSideString.call(this),\n permanentMarkers = filteredEvents.map((event) => {\n const { eventDate, globalDeviceId, id } = event,\n leftPercent = (differenceInSeconds(eventDate, startTime) / timeInterval) * 100;\n\n return createMarkerObject(leftPercent, [id], event, globalDeviceId, sideString);\n }),\n permanentMarkersCollated = getMarkersCollated(permanentMarkers, getRtlSideString.call(this));\n\n return permanentMarkersCollated;\n }\n\n /**\n * Is there any video before the beginning of the current interval displayed in the timeline.\n */\n @computed('args.{areControlsEnabled,earliestTime,startTime}')\n get noVideoAvailableStart(): boolean {\n const { args } = this,\n { areControlsEnabled, earliestTime, startTime } = args;\n\n // If earliestTime doesn't exist, we won't limit the timeline.\n // If earliestTime exists, then it has to be strictly after the startTime for this to be true\n return !areControlsEnabled || (earliestTime?.getTime() || 0) >= (startTime?.getTime() || 0);\n }\n\n /**\n * Is there any video after the end of the current interval displayed in the timeline.\n */\n @computed('args.{endTime,latestTime,areControlsEnabled}')\n get noVideoAvailableEnd(): boolean {\n const { areControlsEnabled, endTime, latestTime } = this.args;\n\n // If latestTime exists, then it has to be strictly before the endTime for this to be true\n return !areControlsEnabled || (latestTime?.getTime() || 0) <= (endTime?.getTime() || 0);\n }\n\n /**\n * Checks that the user is not hovering over a pop-menu and not hovering over a marker. If not, it clears\n * the highlighted events.\n */\n hideHighlightedEventsIfNeeded(): void {\n if (this.mouseLocation === MouseLocation.Other) {\n this.args.eventHover([]);\n }\n }\n\n /**\n * The id of the secondary/orange marker that we should be highlighting (making a little bigger), if there is one.\n */\n @computed('mouseLocation', 'args.highlightedEventIds', 'highlightedPopoverEventId')\n get secondaryMarkerIdToHighlight(): string | null {\n const { mouseLocation, args, highlightedPopoverEventId } = this,\n { highlightedEventIds } = args;\n\n if (highlightedPopoverEventId) {\n return highlightedPopoverEventId;\n }\n\n if (highlightedEventIds?.length !== 1 || mouseLocation === MouseLocation.PrimaryMarker) {\n return null;\n }\n\n return highlightedEventIds[0];\n }\n\n /**\n * The style of the slider thumb (vertical bar the user actually moves on the slider).\n */\n @computed('isDragging', 'sliderPercentage', 'sliderTransitionTime')\n get sliderThumbStyle(): SafeString {\n const { isDragging, sliderPercentage, sliderTransitionTime } = this,\n localizedPercent = getLocalizedPercent.call(this, sliderPercentage),\n // Only animate when we're not dragging\n transitionStyle = isDragging ? '' : 'transition: left ' + sliderTransitionTime + 's';\n\n return htmlSafe(`left: ${localizedPercent}%; ${transitionStyle}`);\n }\n\n /**\n * The style data for the hover slider.\n */\n @computed('tooltipLocation', 'mouseIn', 'isMouseDown', 'mouseInMarkerOrPopover', 'numIndividualStreams')\n get tooltipStyling(): TooltipStyling {\n const { numIndividualStreams, tooltipLocation, mouseIn, mouseInMarkerOrPopover, isMouseDown } = this,\n localizedPercent = getLocalizedPercent.call(this, tooltipLocation),\n visibilityClass = mouseIn && !isMouseDown && !mouseInMarkerOrPopover ? 'visible' : 'hidden';\n\n return {\n iconClass: htmlSafe(`timeline-${numIndividualStreams}x`),\n leftCss: htmlSafe(`left: ${localizedPercent}%`),\n visibilityClass\n };\n }\n\n /**\n * The style of the daybreak marker.\n */\n @computed('args.{endTime,startTime}')\n get daybreakStyle(): SafeString {\n const { args, intl } = this,\n { endTime, startTime } = args;\n\n if (!startTime || !endTime) {\n return htmlSafe('');\n }\n\n // Gets the start time and end time using the timezone of the account.\n const startTimeInTimeZone = utcToZonedTime(startTime, intl.timeZone),\n endTimeInTimeZone = utcToZonedTime(endTime, intl.timeZone),\n midnightInTimeZone = new Date(startTimeInTimeZone.getTime()).setHours(24, 0, 0),\n // The number of milliseconds between start and end time.\n timeDifference = differenceInMilliseconds(endTimeInTimeZone, startTimeInTimeZone),\n markerPercent =\n ((timeDifference - differenceInMilliseconds(endTimeInTimeZone, midnightInTimeZone)) * 100) /\n timeDifference,\n markerPercentRtlSafe = getLocalizedPercent.call(this, markerPercent),\n // If midnight occurs before the timeline's end time, then the marker should use block display,\n // otherwise midnight does not occur between start time and end time, so do not display the marker.\n display = isBefore(midnightInTimeZone, endTimeInTimeZone) ? 'block' : 'none';\n\n return htmlSafe(`left: ${markerPercentRtlSafe}%; display: ${display};`);\n }\n\n /**\n * Minutes increment for collecting thumbnails.\n */\n @computed('timeInterval', 'args.scrubberThumbnailProperties')\n get thumbnailMinutesIncrement(): Array | undefined {\n const { timeInterval, args } = this,\n { scrubberThumbnailProperties } = args;\n\n return scrubberThumbnailProperties?.map((properties) =>\n timeInterval >= NUM_SECONDS_IN_DAY\n ? properties?.minutesBetweenThumbnails?.DayMode || 0\n : properties?.minutesBetweenThumbnails?.HourMode || 0\n );\n }\n\n /**\n * Whether or not the mouse is in a marker or the popover\n */\n @computed('mouseLocation')\n get mouseInMarkerOrPopover(): boolean {\n return [MouseLocation.PrimaryMarker, MouseLocation.SecondaryMarker, MouseLocation.Popover].includes(\n this.mouseLocation\n );\n }\n\n /**\n * Custom 'style' property to be applied to the video-timeline div.\n */\n @computed('numIndividualStreams', 'showAvsThumbnails')\n get timelineStyle(): SafeString {\n const { showAvsThumbnails, numIndividualStreams } = this;\n let height = NO_STREAMS_HEIGHT + numIndividualStreams * INDIVIDUAL_STREAM_HEIGHT;\n\n // If AVS thumbnails aren't being shown, the found search results component is essentially hidden and has no height\n if (showAvsThumbnails && numIndividualStreams) {\n height += AVS_SEARCH_RESULTS_HEIGHT;\n }\n\n return htmlSafe(`height: ${height}px`);\n }\n\n /**\n * If we should show the thumbnail area for the AVS results screen\n * (Some SVRs dont support scrubber thumbnails)\n */\n @computed('args.{avsDataObject,scrubberThumbnailUrls}')\n get showAvsThumbnails(): boolean {\n // only relevant if in an AVS context\n if (!this.args.avsDataObject) {\n return false;\n }\n\n const { scrubberThumbnailUrls } = this.args;\n\n if (!scrubberThumbnailUrls?.length) {\n return false;\n }\n\n return !!scrubberThumbnailUrls?.[0].url;\n }\n\n /**\n * The thumbnail URL list sorted to match the order of the cameras being displayed.\n */\n @computed('args.scrubberThumbnailUrls', 'thumbnailUrlList', 'thumbnailUrlList.@each.globalDeviceId')\n get orderedThumbnailUrlList(): ScrubbedThumbnailUrls[] | null {\n const { args, thumbnailUrlList } = this,\n { scrubberThumbnailUrls } = args,\n orderedThumbnails: ScrubbedThumbnailUrls[] = [];\n if (!scrubberThumbnailUrls || !thumbnailUrlList || !thumbnailUrlList.length) {\n return thumbnailUrlList;\n }\n\n for (let i = 0; i < scrubberThumbnailUrls.length; i++) {\n const thumbnailList: ScrubbedThumbnailUrls | undefined = thumbnailUrlList.findBy(\n 'firstObject.globalDeviceId',\n scrubberThumbnailUrls[i].globalDeviceId\n ) as ScrubbedThumbnailUrls | undefined;\n if (!thumbnailList || !thumbnailList.length) {\n orderedThumbnails.push([]);\n continue;\n }\n\n const thumbnails: ScrubbedThumbnailUrls = [];\n for (let j = 0; j < thumbnailList.length; j++) {\n thumbnails.push({\n url: thumbnailList[j].url,\n globalDeviceId: thumbnailList[j].globalDeviceId,\n cssClass: `scrubber-thumbnail-${i}-${j} hidden`\n });\n }\n\n orderedThumbnails.push(thumbnails);\n }\n\n return orderedThumbnails;\n }\n\n /**\n * Gets the start and end times, rounded to the nearest timeInterval,\n * as well as the total thumbnails that are requested.\n */\n scrubberThumbnailsRequestTimeParameters(streamIndex: number): ScrubberThumbnailRequestTimeParams {\n const { args, thumbnailMinutesIncrement, timeInterval } = this,\n { startTime } = args;\n if (!startTime || !thumbnailMinutesIncrement || !thumbnailMinutesIncrement[streamIndex]) {\n return {};\n }\n\n const numThumbnailsRequired = Math.floor(\n timeInterval / NUM_SECONDS_IN_MINUTE / thumbnailMinutesIncrement[streamIndex]\n ),\n numMillisecondsInThumbnailMinutesIncrement =\n thumbnailMinutesIncrement[streamIndex] * NUM_MILLISECONDS_IN_MINUTE,\n startTimeRoundedByInterval = new Date(\n Math.round((startTime as unknown as number) / numMillisecondsInThumbnailMinutesIncrement) *\n numMillisecondsInThumbnailMinutesIncrement\n ),\n endTimeRoundedByInterval = new Date(\n Math.round(startTimeRoundedByInterval as unknown as number) +\n // The rounded end time is an extra interval later than the timeline end time\n // so that we retrieve an extra thumbnail right at the end time.\n thumbnailMinutesIncrement[streamIndex] * NUM_MILLISECONDS_IN_MINUTE * (numThumbnailsRequired + 1)\n );\n\n return { numThumbnailsRequired, startTimeRoundedByInterval, endTimeRoundedByInterval };\n }\n\n /**\n * List of scrubber thumbnail URLs and CSS class meant to be used by the template/DOM as the default state.\n */\n @restartableTask *getThumbnailUrlListTask(): Generator<\n Promise,\n void,\n ScrubbedThumbnailUrls[]\n > {\n const { args, thumbnailMinutesIncrement, numberOfStreams, preloadScrubberThumbnails, ajax } = this,\n { scrubberThumbnailUrls } = args;\n\n const promises = Array.from({ length: numberOfStreams }, async (_, i) => {\n if (!scrubberThumbnailUrls?.[i]?.url || !thumbnailMinutesIncrement?.[i]) {\n return [];\n }\n\n const { startTimeRoundedByInterval, endTimeRoundedByInterval, numThumbnailsRequired } =\n this.scrubberThumbnailsRequestTimeParameters(i);\n\n if (!startTimeRoundedByInterval || !endTimeRoundedByInterval) {\n // this shouldn't happen, this is just for TS linting.\n return [];\n }\n\n // SD Card allows pre-caching thumbnails, so make the initial prep request.\n if (preloadScrubberThumbnails) {\n const formattedStartTimeUtc = startTimeRoundedByInterval?.toISOString(),\n formattedEndTimeUtc = endTimeRoundedByInterval?.toISOString(),\n prepUrl = `${scrubberThumbnailUrls[i].url}&start=${formattedStartTimeUtc}&end=${formattedEndTimeUtc}&interval=${thumbnailMinutesIncrement[i]}`;\n\n try {\n // Ignore the ajax call in the test environment.\n const response = this.envSettings.isTestEnvironment()\n ? 'True'\n : ((await ajax.request(prepUrl, undefined, undefined, POST, false)) as string);\n\n // If the prep failed, then let's not even try to retrieve any images.\n if (response.toLowerCase() !== 'true') {\n return [];\n }\n } catch {\n return [];\n }\n }\n\n // One additional thumbnail is requested so that there is a thumbnail at the end time of the timeline.\n return Array.from({ length: (numThumbnailsRequired || 0) + 1 }, (_, index) => {\n const requestUrlTime = addSeconds(\n startTimeRoundedByInterval,\n (thumbnailMinutesIncrement[i] || 0) * index * NUM_SECONDS_IN_MINUTE\n ),\n url = getFullUrlForScrubberThumbnail(\n this.envSettings,\n scrubberThumbnailUrls[i].url,\n requestUrlTime,\n thumbnailMinutesIncrement[i]\n );\n\n return {\n url,\n globalDeviceId: scrubberThumbnailUrls[i].globalDeviceId\n };\n });\n });\n\n this.thumbnailUrlList = yield Promise.all(promises);\n }\n\n /**\n * When the events-info-popover is inserted, this is called. We determine what spacing adjustments (if any) we should make for it.\n */\n @action onPopoverInsert(startPercent: number): void {\n const eventInfo = document.querySelector('.events-info-popover .events-info') as HTMLElement,\n timeline = document.querySelector('.video-timeline') as HTMLElement,\n widthRatio = eventInfo.offsetWidth / timeline.offsetWidth,\n overlapAmount = (widthRatio - (100 - startPercent) / 100) * timeline.offsetWidth;\n let marginLeft = DEFAULT_POPOVER_MARGIN_LEFT;\n\n if (overlapAmount > DEFAULT_POPOVER_MARGIN_LEFT * -1) {\n // We want to make sure that the calculated margin left isnt so low or so high that it makes the popover triangle be at the edge (which looks bad)\n marginLeft = Math.min(eventInfo.offsetWidth - POPOVER_SPACING_ADJUSTER, overlapAmount) * -1;\n }\n\n this.eventInfoStyle = `margin-left: ${marginLeft}px`;\n }\n\n /**\n * Handles the mouse down event on the component.\n */\n @action mouseClicked(e: MouseEvent): void {\n if (e.which === 1) {\n // Do not set the isMouseDown variable here, as it could potentially be invalid. Let processPressEvent handle it.\n processPressEvent.call(this, e);\n }\n }\n\n /**\n * Handles the touch event on the component\n */\n @action touchStarted(e: TouchEvent): void {\n processPressEvent.call(this, e);\n }\n\n /**\n * Tells the app what the current time should be when this button is clicked. The app can choose to do whatever with it.\n */\n @action back(): void {\n logEventConditionToWavefront(this.stats, TIMELINE_TIME_UPDATE, false);\n updateTime.call(this, subSeconds(this.args.currentTime || 0, this.timeInterval), TimelineArrowBack);\n }\n\n /**\n * Tells the app what the current time should be when this button is clicked. The app can choose to do whatever with it.\n */\n @action forward(): void {\n logEventConditionToWavefront(this.stats, TIMELINE_TIME_UPDATE, true);\n updateTime.call(this, addSeconds(this.args.currentTime || 0, this.timeInterval), TimelineArrowForward);\n }\n\n /**\n * Debounces the function to get the list of thumbnail URLs if the scrubber URL list is valid.\n */\n @action\n getThumbnailUrlListDebounced(): void {\n const { args } = this,\n { scrubberThumbnailUrls, timelineChangeDebounceTimeMs } = args;\n\n if (!scrubberThumbnailUrls || !scrubberThumbnailUrls.length) {\n return;\n }\n\n // Reset list to avoid showing incorrect thumbnails if, for example, the camera group has changed.\n this.thumbnailUrlList = null;\n\n // Debounce the call to VideoRelay to avoid excessive network calls and unnecessary queueing of requests sent to the camera.\n // Do not copy this deprecated usage. If you see this, please convert to ember-lifeline debounceTask.\n // eslint-disable-next-line ember/no-runloop\n debounce(this, this.getThumbnailUrlList, timelineChangeDebounceTimeMs);\n }\n\n /**\n * An event inside a popover was just hovered by the users mouse. (or if eventId is null, was just unhovered)\n */\n @action popoverEventHover(eventId: string): void {\n this.highlightedPopoverEventId = eventId;\n }\n\n /**\n * Handles the mouse enter event.\n */\n @action handleMouseEnter(): void {\n if (!this.args.areControlsEnabled) {\n return;\n }\n\n set(this, 'mouseIn', true);\n\n // Only do the hover event if the mouse is not down. If it is, then the user would already be dragging and\n // the time tooltip is not required.\n if (!this.isMouseDown) {\n processHoverEvent.call(this);\n }\n }\n\n /**\n * Handles the mouse leave event.\n */\n @action handleMouseLeave(): void {\n set(this, 'mouseIn', false);\n\n // Hide any scrubber thumbnail image.\n hideScrubberThumbnails.call(this);\n\n // Only remove the listeners if the mouse is not down. If it is, the we'll let the mouseUp event handle it\n if (!this.isMouseDown) {\n removeTimelineDomListeners.call(this);\n }\n }\n\n /**\n * Shows the hover object when the user highlights over a marker.\n */\n @action showMarkerHover(eventIds: string[], fromPrimaryMarker: boolean): void {\n this.mouseLocation = fromPrimaryMarker ? MouseLocation.PrimaryMarker : MouseLocation.SecondaryMarker;\n this.scrubberThumbnailHoverOut();\n this.args.eventHover(eventIds);\n }\n\n /**\n * On initialize, move the slider to the correct position to.\n */\n @action onInsert(): void {\n // Validate all values\n const { args } = this,\n { currentTime, endTime, startTime } = args;\n\n if (!currentTime || !startTime || !endTime) {\n // These three things need to be declared or else we won't be able to do anything\n console.error('Initialization failed');\n return;\n }\n\n set(this, 'thumbnailCache', new Map());\n\n const percentage = getSliderPercentageFromTime.call(this, currentTime);\n\n // Sets the initial time on render\n updateSliderPercentage.call(this, percentage || 0);\n }\n\n /**\n * When mousing out of the popover connector, we want to see if the user moused out from the side (as opposed to the top), in which case\n * we should hide the popover.\n */\n @action onPopoverConnectorMouseOut(event: MouseEvent): void {\n const popoverConnector = document.querySelector('.events-info-popover .popover-connector') as HTMLElement,\n leavingConnectorFromSides = event.offsetX < 0 || event.offsetX >= popoverConnector.offsetWidth;\n\n set(this, 'mouseLocation', leavingConnectorFromSides ? MouseLocation.Other : MouseLocation.Popover);\n this.hideHighlightedEventsIfNeeded();\n }\n\n /**\n * updates that we are no longer hovering over the marker\n */\n @action onMarkerMouseOut(index: number, event: MouseEvent): void {\n /**\n * For context, the hitbox from the marker should reach out to the popover given the implementation\n * for the marker-popover-boundary-connector. This allows for the popover to stay expanded when the\n * mouse is in the area between the dot on the timeline and the popover. Once we've moved outside of\n * the marker / expanded hitbox area, we will hit this and need to check whether the mouse is in the\n * popover (and we should keep it expanded) or outside the popover (and can go ahead and close it out).\n */\n const popoverConnector = document.querySelector('.events-info-popover .popover-connector');\n\n set(\n this,\n 'mouseLocation',\n popoverConnector === event.relatedTarget ? MouseLocation.Popover : MouseLocation.Other\n );\n\n this.scrubberThumbnailHoverIn(index);\n this.hideHighlightedEventsIfNeeded();\n }\n\n /**\n * sets whether or not the user is hovering over the popover menu on the timeline, and if not, delete the menu.\n */\n @action setInPopoverValue(inPop: boolean): void {\n set(this, 'mouseLocation', inPop ? MouseLocation.Popover : MouseLocation.Other);\n this.hideHighlightedEventsIfNeeded();\n }\n\n /**\n * Triggers when mousing over an individual timeline stream element to load and display the scrubber thumbnail.\n *\n * @param index The index of the stream triggering the hover event\n */\n @action scrubberThumbnailHoverIn(index: number): void {\n // Ignore invalid triggers.\n if (!this.args.areControlsEnabled || this.isMouseDown) {\n return;\n }\n\n this.dom.removeListener(this, 'scrubberMoveListener');\n\n set(this, 'hoveredStreamIndex', index);\n set(\n this,\n 'scrubberMoveListener',\n this.dom.addListener(this, window.document.body, 'mousemove', mouseMoveHoverForStream.bind(this))\n );\n }\n\n /**\n * Clean up for scrubber thumbnails when moving mouse off of an individual timeline stream element.\n */\n @action scrubberThumbnailHoverOut(): void {\n if (!this.args.areControlsEnabled) {\n return;\n }\n\n this.dom.removeListener(this, 'scrubberMoveListener');\n set(this, 'hoveredStreamIndex', null);\n hideScrubberThumbnails.call(this);\n }\n\n /**\n * Show the paused recording schedule tool tip at the index\n */\n @action setPausedToolTipIndex(index: number): void {\n this.pausedToolTipVisibleIndex = index;\n }\n\n /**\n * Moves the slider to denote the new time when the user is no longer performing a mouseDown event.\n */\n @action updateCurrentTimeSlider(): void {\n const { isMouseDown, args } = this,\n { currentTime } = args;\n\n if (!isMouseDown) {\n const sliderPercentage = getSliderPercentageFromTime.call(this, currentTime);\n\n // Sometimes we don't get all 3 observed properties update correctly together, so we want to validate the computed result before updating the UX.\n if (sliderPercentage !== undefined && isBetween(sliderPercentage, 0, 100)) {\n updateSliderPercentage.call(this, sliderPercentage);\n }\n }\n }\n\n /**\n * Performs the task to get the list of scrubber thumbnail URLs that will be used to display the image when hovering over the timeline.\n */\n private getThumbnailUrlList(): void {\n const { getThumbnailUrlListTask, thumbnailUrlTaskInfo } = this;\n\n // TODO: This ignore is an existing deprecation that must be refactored, do not copy this usage\n // eslint-disable-next-line @adc/ember/no-is-destroyed\n if (isDestroyed(this)) {\n return;\n }\n\n // Cancel the task to get the list of thumbnail URLs so the timeline doesn't show thumbnails from the wrong time.\n if ((getThumbnailUrlListTask as any).isRunning) {\n (thumbnailUrlTaskInfo as any)?.cancel();\n }\n\n this.thumbnailUrlTaskInfo = (getThumbnailUrlListTask as any).perform();\n }\n}\n\ndeclare module '@glint/environment-ember-loose/registry' {\n export default interface Registry {\n 'Video::VideoTimeline': typeof TimeLineComponent;\n }\n}\n","import { precompileTemplate } from \"@ember/template-compilation\";\nexport default precompileTemplate(\"\\n{{! @glint-nocheck: This component doesn\\'t seem to have it\\'s arguments defined, so we can\\'t enable glint until that is fixed. }}\\n{{yield}}\\n\\n{{#let this.layoutControl.layoutProperties as |layoutProps|}}\\n \\n \\n \\n
    \\n {{#if @model.cameras.length}}\\n {{#if this.useStreamingToolbar}}\\n \\n \\n \\n {{/if}}\\n\\n {{#if this.noActiveCameras}}\\n
    \\n
    \\n
    \\n
    \\n
    {{t \\'generic.noResults\\'}}
    \\n
    \\n
    \\n
    \\n
    \\n {{else}}\\n {{!-- This section is always in dark mode when in theater or full screen mode - the theater experience ;) --}}\\n
    \\n
    \\n
    \\n \\n {{#if this.showPagination}}\\n \\n {{/if}}\\n
    \\n {{#if @model.videoStreamingPermissions.canViewEventSidebar}}\\n
    \\n \\n\\n {{#unless this.usingEventHistorySidebar}}\\n \\n {{/unless}}\\n
    \\n {{/if}}\\n
    \\n {{#if @avsDataObject}}\\n \\n {{/if}}\\n {{#if @appearanceSearchDataObject}}\\n \\n {{/if}}\\n\\n \\n
    \\n
    \\n
    \\n \\n\\n
    \\n
    \\n \\n
    \\n \\n \\n
    \\n
    \\n \\n
    \\n
    \\n\\n
    \\n {{#unless this.isOperatorSite}}\\n {{#if this.playbackControl.currentTime}}\\n \\n {{/if}}\\n {{/unless}}\\n\\n {{#unless this.lockTimelineBoundsToAvailableVideo}}\\n
    \\n \\n \\n
    \\n {{/unless}}\\n {{#if this.hasAttributeSearch}}\\n \\n {{/if}}\\n {{#if this.showCollapseSidebarControl}}\\n
    \\n \\n\\n {{#unless this.usingDefaultFilter}}\\n \\n {{/unless}}\\n
    \\n {{/if}}\\n
    \\n
    \\n\\n \\n
    \\n \\n\\n {{#if this.loadingStreamInformation}}\\n \\n {{/if}}\\n
    \\n {{/if}}\\n {{else}}\\n \\n
    \\n \\n

    {{t this.resourceKeys.hasServicePlan}}

    \\n \\n
    \\n
    \\n {{/if}}\\n
    \\n \\n
    \\n\\n \\n{{/let}}\",{ moduleName: \"customer-site/components/video/video-player/playback-features/index.hbs\" })","/* import __COLOCATED_TEMPLATE__ from './index.hbs'; */\nimport { tracked } from '@glimmer/tracking';\nimport {\n D_KEY,\n EQUALS_KEY,\n LEFT_ARROW_KEY,\n LEFT_BRACKET_KEY,\n RIGHT_ARROW_KEY,\n RIGHT_BRACKET_KEY,\n SPACE_KEY,\n nodeHandlesKeyboardInput,\n nodeHandlesSpaceOrEnterInput\n} from '@adc/ember-utils/utils/a11y';\nimport { areArraysSame } from '@adc/ember-utils/utils/array';\nimport { isDestroyed } from '@adc/ember-utils/utils/ember-helpers';\nimport { set, computed, setProperties, action } from '@ember/object';\nimport { get } from '@ember/object';\nimport { gt, notEmpty, equal, reads } from '@ember/object/computed';\nimport { next, debounce } from '@ember/runloop';\nimport { inject as service } from '@ember/service';\nimport { htmlSafe } from '@ember/template';\nimport { task, timeout } from 'ember-concurrency';\nimport DateTimePickerModal from 'customer-site/components/modals/date-time-picker/index';\nimport {\n ALL_CAMERAS_ID,\n getCameraItemByGlobalDeviceId,\n setCameraProperties\n} from 'customer-site/components/video/video-streaming/video-streaming-features/camera-items';\nimport VideoStreamingFeatures, {\n addLocationGroupsToCameraGroups,\n eventFiredWithModifier,\n setInitialSetupDone,\n updateCameraGroupAndCamera,\n VideoStreamingFeaturesType\n} from 'customer-site/components/video/video-streaming/video-streaming-features/index';\nimport { PlaybackPagesEventHistoryItems } from 'customer-site/enums/CustomerEventHistoryEventFilter';\nimport {\n EmberEnterpriseVideoAdvancedVideoSearch,\n EmberVideoAdvancedVideoSearch\n} from 'customer-site/enums/CustomerPageUrl';\nimport { VideoAddNewDevice } from 'customer-site/enums/CustomerPageUrl';\nimport ForcedStreamingMethodEnum from 'customer-site/enums/ForcedStreamingMethod';\nimport { Highest } from 'customer-site/enums/Resolution';\nimport { StreamUsage } from 'customer-site/enums/StreamUsage';\nimport {\n ActivityEvent,\n AutoSkipGap,\n DateTimePicker,\n PageChange,\n SeekBack,\n SeekForward,\n TimelineClick\n} from 'customer-site/enums/TrackedEvent';\nimport {\n DISCONNECTED_STATE,\n FROZEN_STATE,\n INITIALIZING_STATE,\n LOADING_STATE,\n PLAYING_STATE,\n READY_STATE,\n NOT_VISIBLE_STATE\n} from 'customer-site/enums/VideoPlayerStateEnum';\nimport {\n NoError,\n PlaybackEnded,\n PlaybackStreamConnectionFailed,\n PlaybackStreamTimeout,\n StreamDisconnected,\n StunReconnectionFailed\n} from 'customer-site/enums/VideoSourceError';\nimport { NUM_SECONDS_IN_DAY, NUM_SECONDS_IN_HOUR, NUM_MILLISECONDS_IN_MINUTE } from 'customer-site/utils/datetime';\nimport {\n COOKIE_HIDE_SIDEBAR,\n COOKIE_INTERVAL,\n COOKIE_USE_COLLAPSED_TIMELINE,\n storeCookieForPage\n} from 'customer-site/utils/video/cookies';\nimport { reloadVideoSource } from 'customer-site/utils/video/general';\nimport {\n DOWNLOAD_CLIP,\n PLAYBACK_DATE_PICKER,\n PLAYBACK_EXPAND_COLLAPSE_TIMELINE,\n PLAYBACK_INTERVAL,\n PLAYBACK_SEEK,\n PLAYBACK_SIDEBAR_OPEN_CLOSE,\n TIMELINE_EVENT_POPOVER,\n logEventConditionToWavefront\n} from 'customer-site/utils/video/wavefront-stats';\nimport { getContextAwareThumbnailSearchPage } from 'customer-site/video/thumbnail-search/route';\nimport { sentryWithScopeAndError } from '@adc/app-infrastructure/utils/sentry';\nimport { downloadCrossOriginImage } from '@adc/ui-components/utils/download-file';\nimport DropdownSelectItem from '@adc/ui-components/utils/dropdown-select-item';\nimport { Log } from '@adc/video-player/constants/player-messages';\nimport { isAfter, isEqual, startOfDay, eachDayOfInterval } from 'date-fns';\nimport addMilliseconds from 'date-fns/addMilliseconds';\nimport addSeconds from 'date-fns/addSeconds';\nimport differenceInMilliseconds from 'date-fns/differenceInMilliseconds';\nimport differenceInSeconds from 'date-fns/differenceInSeconds';\nimport subSeconds from 'date-fns/subSeconds';\nimport { setWebStreamingLogType } from '../base-video-player';\nimport IntervalsControl, { IntervalSetting, NextAvailableTimeAction } from './intervals-control';\nimport { getCamerasCountInState } from './page-state';\nimport PlaybackControl from './playback-control';\n\nimport type { ModalComponent } from '@adc/ui-components/services/modals';\nimport type { AppNotification } from '@adc/ui-components/services/notification-manager';\nimport type ArrayProxy from '@ember/array/proxy';\nimport type { SafeString } from '@ember/template';\nimport type HistoryEvent from 'customer-site/models/activity/history-event';\nimport type HistoryEventFilter from 'customer-site/models/activity/history-event-filter';\nimport type LocationModel from 'customer-site/models/enterprise/locations/location';\nimport type CameraGroup from 'customer-site/models/video/camera-group';\nimport type Camera from 'customer-site/models/video/devices/camera';\nimport type DewarpConfig from 'customer-site/models/video/dewarp-config';\nimport type VideoStreamingPermissionsCollection from 'customer-site/models/video/permissions/video-streaming-permissions-collection';\nimport type SdCardThumbnailEndpoint from 'customer-site/models/video/sd-card-thumbnail-endpoint';\nimport type SdCardVideoSource from 'customer-site/models/video/video-sources/sd-card-video-source';\nimport type SvrVideoSource from 'customer-site/models/video/video-sources/svr-video-source';\nimport type IdentityManager from 'customer-site/services/identity-manager';\nimport type NavigationService from 'customer-site/services/navigation';\nimport type VisualVerification from 'customer-site/services/visual-verification';\nimport type { AppearanceSearchDataObject } from 'customer-site/video/appearance-search-results/controller';\nimport type { BasePlaybackModel } from 'customer-site/video/base-playback-route';\nimport type { Task } from 'ember-concurrency';\nimport type ModelRegistry from 'ember-data/types/registries/model';\nimport type SvrThumbnailEndpoint from '../../../../models/video/svr-thumbnail-endpoint';\nimport type {\n CameraItem,\n Dimensions,\n OEAudioInfo,\n PlayerInfo\n} from '../../video-streaming/video-streaming-features/types';\nimport type {\n AllStreamsIntervals,\n ResourceKeys,\n ScrubbedThumbnailUrls,\n ScrubberThumbnailProperties,\n DirectDownloadAndClipsDurations,\n CamerasDataObject\n} from './types';\nimport './_style.scss';\n\n// region Private Constants.\n\n/**\n * Clip export options.\n * ExportOptionDirectDownload: direct download clip to local.\n * ExportOptionAddToSavedClips: save clip to the cloud.\n * ExportOptionDirectDownloadAddToSavedClips: direct download clip to local and save clip to the cloud.\n */\nexport const ExportOptionDirectDownload = 0,\n ExportOptionAddToSavedClips = 1,\n ExportOptionDirectDownloadAddToSavedClips = 2;\n\n/**\n * When navigating to an event, how many seconds should there be before the event actually occurs in the video.\n */\nconst EventOffset = 5;\n\n/**\n * How many milliseconds the sidebar button flashing animation should take.\n */\nconst SidebarButtonFlashingMilliseconds = 500;\n\n/**\n * Available durations (in seconds) from which a user may pick for thumbnail downloads.\n */\nconst ThumbnailsDownloadDurations = [\n // 30 minutes.\n 1800,\n // 1 hour.\n NUM_SECONDS_IN_HOUR,\n // 3 hours.\n 10800,\n // 6 hours.\n 21600,\n // 12 hours.\n 43200,\n // 18 hours.\n 64800,\n // 1 day.\n NUM_SECONDS_IN_DAY\n];\n\nconst SidebarAnimationMilliseconds = 300;\n\nconst FailureIconTimeoutMilliseconds = 2000;\n\n// endregion Private Constants.\n\n/**\n * If the globalDeviceId passed in matches one of the streams on the screen.\n */\nfunction deviceIdMatchesSelectedDevices(globalDeviceId: string, cameraItems: CameraItem[]): boolean {\n return !!getCameraItemByGlobalDeviceId(globalDeviceId, cameraItems);\n}\n\n/**\n * Retrieves the players object for the globalDeviceId selected.\n */\nfunction getPlayerByDeviceId(cameraGlobalDeviceId: string, cameraItems: CameraItem[]): PlayerInfo | undefined {\n const cameraItem = getCameraItemByGlobalDeviceId(cameraGlobalDeviceId, cameraItems);\n\n if (!cameraItem) {\n return undefined;\n }\n\n return cameraItem.player;\n}\n\n/**\n * @classDesc\n *\n * Player with base playback player and playback features/controls.\n */\nexport default class PlaybackFeatures extends VideoStreamingFeatures {\n @service declare navigation: NavigationService;\n @service declare visualVerification: VisualVerification;\n @service declare identityManager: IdentityManager;\n\n // region Hooks.\n\n constructor(owner: any) {\n super(owner);\n this.playbackControl = new PlaybackControl(\n this.intl.timeZone,\n this.envSettings,\n this.playbackInfoCacheManager,\n this.setPlayerUrls.bind(this),\n this.moveToNextAvailableStartTime.bind(this),\n this.stats,\n this.ajax,\n () => {\n return this.playbackStateControllers;\n }\n );\n this.intervalsControl = new IntervalsControl(this.playbackInfoCacheManager);\n\n setWebStreamingLogType.call(this);\n }\n\n /** @override */\n // Do not copy this deprecated usage. If you see this, please fix\n // eslint-disable-next-line ember/classic-decorator-hooks\n init() {\n const { model, ajax, store, initialTimeInterval } = this;\n\n setCameraProperties(\n model.cameras,\n {\n isPaused: false\n },\n ALL_CAMERAS_ID\n );\n\n // Set default empty values.\n this.eventTypeFilters = null;\n\n this.playbackControl.setSpeedValues(0, this.availableSpeeds);\n this.changeTimeInterval(initialTimeInterval, false);\n\n this.playbackControl.setPlayerType(this.playerType);\n this.intervalsControl.setPlayerType(this.playerType);\n\n // Reset the times to their default values.\n this.resetTimes();\n\n if (model.cameras.length) {\n // Load event history with the default times.\n this.loadEventHistory();\n\n // Get video event filters and set when ready.\n this.eventTypeFilters = ajax\n .apiRequest('activity/historyEventFilters/getVideoEventFilters')\n // TODO: This ignore is an existing deprecation that must be refactored, do not copy this usage\n // eslint-disable-next-line @adc/ember/no-is-destroyed\n .then((result: HistoryEventFilter[]) => (isDestroyed(this) ? [] : store.push(result))) as Promise<\n HistoryEventFilter[]\n >;\n\n this.highlightedEventIds = [];\n }\n\n // Giving the parent of this component the ability to select the time window\n this.setSelectTimeWindowMethod((newTimelineStartTime, newCurrentTime) => {\n newCurrentTime =\n newCurrentTime ?? new Date(newTimelineStartTime.getTime() + NUM_MILLISECONDS_IN_MINUTE * 30);\n\n this.updateCurrentTime(newCurrentTime);\n this.updateTimelineAndLoadThumbnailsAndEvents(newTimelineStartTime);\n });\n\n return super.init();\n }\n\n // endregion Hooks.\n\n // region Overrides.\n\n /** @override */\n get componentType() {\n return VideoStreamingFeaturesType.Playback;\n }\n\n /**\n * The largest value allowed for the max videos per page in auto view\n * This is 16 by default, but 4 in playback pages. (Due to certain device restrictions)\n */\n autoViewMaxVideosPerPageLimit = 4;\n\n // endregion Overrides.\n\n // region Properties.\n\n /**\n * The playback features model info passed in\n */\n declare model: BasePlaybackModel;\n\n /**\n * Enforce the usage of the same template for the extended classes.\n */\n layoutName = 'components/video/video-player/playback-features';\n\n /**\n * The enums for seeking (for the template to access them)\n */\n seekEnums = {\n back: SeekBack,\n forward: SeekForward\n };\n\n /**\n * Determines if playback should always go through the proxy.\n */\n @equal('forcedStreamingMethodFromQueryParam', ForcedStreamingMethodEnum.ForceWebRTCProxy)\n declare forceProxyFromQueryParam: boolean;\n\n /**\n * The intervalsControl which manages the recording intervals for this page.\n */\n @tracked\n intervalsControl: IntervalsControl;\n\n /**\n * A control for playback related features\n */\n @tracked\n playbackControl: PlaybackControl;\n\n /**\n * Should we force a STUN stream during an end-to-end stream load with extended timeouts?\n */\n @tracked\n shouldForceEndToEndWithExtendedTimeouts = false;\n\n /**\n * Determines if we should skip thumbnail precaching and load individual images on demand.\n */\n individualThumbnailMode = false;\n\n /**\n * Download clip modal component path.\n */\n clipDownloadModalComponent: ModalComponent | null = null;\n\n /**\n * Download thumbnails modal component path.\n */\n thumbnailsDownloadModalComponent: ModalComponent | null = null;\n\n /**\n * The name of the endpoint for retrieving thumbnails from the camera, ie camera.get(scrubberThumbnailEndpoint)\n */\n scrubberThumbnailEndpoint: string | null = null;\n\n /**\n * The name of the endpoint for retrieving the video source for the device\n */\n videoSourceEndpoint: string | null = null;\n\n /**\n * The path to the video source model.\n */\n videoSourceModelPath: keyof ModelRegistry | null = null;\n\n /**\n * The list of filters which could be applied.\n */\n eventTypeFilters: Promise | null = null;\n\n /**\n * The type of the log the WebRTC/OE stream is sending (SVR, SD Card, Live View, Live View Analytics, Live View FOV).\n */\n webStreamingLogType?: number;\n\n /**\n * The base resource path to use for translations.\n * Must be overridden.\n */\n baseResourcePath: string | null = null;\n\n /**\n * The time in milliseconds to debounce certain functions dealing with the timeline,\n * including thumbnail requests to VideoRelay and retrieving event history.\n */\n timelineChangeDebounceTimeMs = 50;\n\n /**\n * Should we enable the Advanced Video Search link?\n */\n enableAdvancedVideoSearch = false;\n\n /**\n * How many seconds to display on the timeline. (this is usually NUM_SECONDS_IN_HOUR or NUM_SECONDS_IN_DAY)\n */\n initialTimeInterval = NUM_SECONDS_IN_HOUR;\n\n /**\n * Should the timeline start and end be bound to the available video?\n */\n lockTimelineBoundsToAvailableVideo = false;\n\n /**\n * The name of the property on the camera model for determining whether the camera supports downloading thumbnails.\n */\n supportsDownloadingThumbnailsProperty: string | null = null;\n\n /**\n * Appearance search specific data\n */\n appearanceSearchDataObject?: AppearanceSearchDataObject;\n\n /**\n * Is this an Operator Site session?\n */\n @reads('identityManager.identityModel.isVisualVerification')\n declare isOperatorSite: boolean;\n\n /**\n * The method to call, if we fail to set the intervals for the device/s\n */\n onSetIntervalsFailed: VoidFunction = () => {};\n\n /**\n * Change the page number\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n updatePage: (newPageNumber: number) => void = (_newPageNumber) => {};\n\n /**\n * Change the selected AVS result to a new index\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n changeSelectedAvsResult: (newIndex: number) => void = (_newIndex) => {};\n\n /**\n * A method for changing the current time and timeline start time\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n setSelectTimeWindowMethod = (_callback: (newTimelineStartTime: Date, newCurrentTime?: Date) => void) => undefined;\n\n // endregion Properties.\n\n // region Tracked Properties.\n\n /**\n * A start time value (as an ISO string) that is an optional argument for manually setting where playback should start at\n */\n @tracked\n startTime?: string;\n\n /**\n * List of base URLs for getting scrubber thumbnails.\n */\n @tracked\n scrubberThumbnailUrls: ScrubbedThumbnailUrls | null = null;\n\n /**\n * Is the stream information currently loading?\n */\n @tracked\n loadingStreamInformation = false;\n\n /**\n * The activity history events to display.\n */\n @tracked\n events: HistoryEvent[] | null = null;\n\n /**\n * If the coverage data has loaded for the initial device(s) selected.\n */\n @tracked\n initialStreamDataLoaded = false;\n\n /**\n * The events to highlight.\n */\n @tracked\n highlightedEventIds: string[] = [];\n\n /**\n * The filter function applied to components containing events.\n */\n @tracked\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n filterFn = (_eventId: number, _deviceTypeFilterIds: number[], _ovClassification: number, _globalDeviceId: string) =>\n true;\n\n /**\n * Whether we should use the collapsed timeline display mode (as opposed to the expanded display mode).\n */\n @tracked\n collapsedModeForTimeline = false;\n\n /**\n * Whether the user has used the hide/show sidebar toggle button yet.\n */\n @tracked\n sidebarToggleHasBeenUsed = false;\n\n /**\n * If the sidebar button is flashing. This is used to highlight it visually to a user.\n */\n @tracked\n sidebarButtonIsFlashing = false;\n\n /**\n * Whether we should hide the sidebar/event-history.\n */\n @tracked\n hideSidebar = true;\n\n /**\n * If the event history sidebar is the sidebar being used. False means we're using the appearance search sidebar\n */\n @tracked\n usingEventHistorySidebar = true;\n\n /**\n * The dimensions of the video player.\n */\n @tracked\n dynamicVideoPlayerDimensions: Dimensions | null = null;\n\n /**\n * If we are currently using the default event filtering for the selected device(s).\n */\n @tracked\n usingDefaultFilter = true;\n\n /**\n * Does the user have video analytics read access?\n */\n @tracked\n hasVideoAnalyticsReadAccess = true;\n\n /**\n * If we have the attribute search feature\n */\n @tracked\n hasAttributeSearch = false;\n\n /**\n * Does the user have permission to edit camera groups?\n */\n @tracked\n canEditCameraGroups = true;\n\n /**\n * Properties about the scrubber thumbnails.\n * minutesBetweenThumbnails is the number of minutes between each thumbnail,\n * and contains a value for both DayMode and HourMode.\n * aspectRatio is the width divided by height that should be used when displaying the thumbnail.\n */\n @tracked\n scrubberThumbnailProperties?: ScrubberThumbnailProperties = undefined;\n\n // endregion Tracked Properties.\n\n // region Computed Properties.\n\n /**\n * Does this playback player support clip downloads?\n */\n @notEmpty('clipDownloadModalComponent')\n declare supportsClipDownload: boolean;\n\n /**\n * Does the playback player support downloading thumbnails?\n */\n @notEmpty('thumbnailsDownloadModalComponent')\n declare playerTypeSupportsDownloadingThumbnails: boolean;\n\n /**\n * If this is in an SD context (as opposed to SVR)\n */\n @equal('playerType', StreamUsage.SDCard)\n declare isSdCardComponent: boolean;\n\n /**\n * Should the volume button be disabled?\n * Camera audio will not work when the player speed is anything more than 1x.\n */\n @gt('speed', 1)\n declare disableVolumeButton: boolean;\n\n /**\n * Video clip export options.\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n getClipExportOptions(_deviceId: string): number[] {\n return [ExportOptionDirectDownload];\n }\n\n /**\n * Returns the forced streaming method enum assigned currently.\n * This will override the default streaming connection method.\n */\n @computed('shouldForceEndToEndWithExtendedTimeouts', 'forcedStreamingMethodFromQueryParam')\n get forcedStreamingMethod(): ForcedStreamingMethodEnum {\n return this.shouldForceEndToEndWithExtendedTimeouts\n ? ForcedStreamingMethodEnum.ForceWebRTCEndToEnd\n : this.forcedStreamingMethodFromQueryParam;\n }\n\n /**\n * Whether the streaming toolbar will be made visible on the page.\n */\n @computed('cameras.length', 'appearanceSearchDataObject')\n get useStreamingToolbar(): boolean {\n // we hide the toolbar if there are no cameras or we are on the appearance search page\n return !!this.cameras?.length && !this.appearanceSearchDataObject;\n }\n\n /**\n * The timeline start time formatted like 'Jun 22, 2021'.\n */\n @computed('intl', 'playbackControl.timelineStartTime')\n get formattedTimelineStartDate(): string {\n const { timelineStartTime } = this.playbackControl;\n if (!timelineStartTime) {\n return '';\n }\n\n return this.intl.formatDateTz(timelineStartTime, {\n year: 'numeric',\n month: 'short',\n day: 'numeric'\n });\n }\n\n /**\n * The timeline end time formatted like 'Jun 22, 2021'.\n */\n @computed('intl', 'playbackControl.timelineEndTime')\n get formattedTimelineEndDate(): string {\n const { timelineEndTime } = this.playbackControl;\n if (!timelineEndTime) {\n return '';\n }\n\n return this.intl.formatDateTz(timelineEndTime, {\n year: 'numeric',\n month: 'short',\n day: 'numeric'\n });\n }\n\n /**\n * Are the controls disabled?\n *\n * @returns Whether the user is able to interact with the timeline controls and player.\n */\n @computed('playbackControl.pageState', 'intervalsControl.{allStreamsIntervals,isCoverageLoaded}')\n get disabled(): boolean {\n const { intervalsControl, playbackControl } = this,\n { pageState } = playbackControl,\n { allStreamsIntervals, isCoverageLoaded } = intervalsControl,\n hasIntervals = allStreamsIntervals?.some(({ intervals }) => intervals && intervals.length > 0);\n\n return !hasIntervals || !isCoverageLoaded || [INITIALIZING_STATE, LOADING_STATE].includes(pageState);\n }\n\n /**\n * The player-specific resource keys for when the user doesn't have any schedules\n * or any devices that supports recording for this playback type.\n */\n @computed('baseResourcePath')\n get resourceKeys(): ResourceKeys {\n const { baseResourcePath } = this;\n if (!baseResourcePath) {\n throw new Error('baseResourcePath must be overridden.');\n }\n\n return {\n hasServicePlan: baseResourcePath + 'hasServicePlan',\n addSchedule: baseResourcePath + 'addSchedule',\n addDevice: baseResourcePath + 'addDevice'\n };\n }\n\n /**\n * The hover text string for the expandCollapseTimeline button.\n */\n @computed('intl', 'collapsedModeForTimeline')\n get expandCollapseTimelineButtonText(): string {\n const textKey = `components.video.video-player.playback-features.${\n this.collapsedModeForTimeline ? 'expandTimeline' : 'collapseTimeline'\n }`;\n\n return this.intl.t(textKey);\n }\n\n /**\n * The hover text string for the showHideSidebar button.\n */\n @computed('intl', 'hideSidebar')\n get showHideSidebarButtonText(): string {\n const textKey = `components.video.video-player.playback-features.${\n this.hideSidebar ? 'showSidebar' : 'hideSidebar'\n }`;\n\n return this.intl.t(textKey);\n }\n\n /**\n * If we should show the collapse sidebar control\n */\n @computed('avsDataObject', 'model.videoStreamingPermissions.canViewEventSidebar')\n get showCollapseSidebarControl(): boolean {\n return !this.avsDataObject && !!get(this.model, 'videoStreamingPermissions.canViewEventSidebar');\n }\n\n /**\n * Disable play or pause button while all controls are disabled, and pause button while page state is loading.\n */\n @computed(\n 'avsDataObject.searchFailed',\n 'disabled',\n 'playbackControl.{isTimelineButtonDisplayingPlayIcon,pageState}'\n )\n get disablePlayPauseButton(): boolean {\n return (\n this.disabled ||\n (!this.playbackControl.isTimelineButtonDisplayingPlayIcon &&\n this.playbackControl.pageState === LOADING_STATE) ||\n this.avsDataObject?.searchFailed ||\n false\n );\n }\n\n /**\n * The list of speed options to be populated in the dropdown.\n */\n @computed('availableSpeeds')\n get speedOptions(): DropdownSelectItem[] {\n return this.availableSpeeds.map((speed) =>\n DropdownSelectItem.create({ name: speed + 'x', value: speed.toString() })\n );\n }\n\n /**\n * Style string for width and height for a single video player.\n */\n @computed('singlePlayerDimensions')\n get singlePlayerDimensionsStyle(): SafeString {\n const { layoutControl } = this,\n { singlePlayerDimensions } = layoutControl;\n\n if (!singlePlayerDimensions) {\n return htmlSafe('');\n }\n\n return htmlSafe(`height:${singlePlayerDimensions.height}px;width:${singlePlayerDimensions.width}px`);\n }\n\n /**\n * Returns a combined object of cameraItems, activeCameras, and the cameras model.\n * For code minimization, since these are often needed at the same time.\n */\n @computed('cameraItems', 'activeCameras', 'model.cameras')\n get camerasDataObject(): CamerasDataObject {\n const { cameraItems, activeCameras, model } = this;\n return { cameraItems, activeCameras, camerasModel: model.cameras };\n }\n\n /**\n * Gets the list of device IDs that are currently displaying on the page.\n */\n @computed('cameraItems')\n get deviceIdsDisplayingOnPage(): string[] {\n return this.cameraItems?.map((cameraItem) => cameraItem.model?.id).compact() || [];\n }\n\n // endregion Computed Properties.\n\n // region Abstract Functions and Properties.\n\n /**\n * Set player URLs (playback URL, delete URL, etc.).\n * Additional processing needed when starting playback.\n * Must be overridden.\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n setPlayerUrls(_player: PlayerInfo, _deviceId: string, _currentTime: Date, _videoEndTime: Date): Promise {\n throw new Error('setPlayerUrls must be overridden.');\n }\n\n /**\n * Retrieves motion intervals for the current time window and replaces the motion intervals from the allStreamsIntervals object\n * with the intervals retrieved.\n */\n loadMotionIntervals(): void {\n throw new Error('loadMotionIntervals must be overridden');\n }\n\n /**\n * Retrieves clip download durations for a specific camera\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n getClipDownloadDurations(_deviceId: string): number[] {\n throw new Error('getClipDownloadDurations must be overridden');\n }\n\n /**\n * Retrieves clip upload durations for a specific camera.\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n getClipUploadDurations(_deviceId: string): number[] {\n throw new Error('getClipUploadDurations must be overridden');\n }\n\n /**\n * Retrieves clip download/upload durations for a specific camera.\n */\n getClipDurations(deviceId: string): DirectDownloadAndClipsDurations {\n const clipDownloadDurations = this.getClipDownloadDurations(deviceId);\n const clipUploadDurations = this.getClipUploadDurations(deviceId);\n const downloadAndUploadDurations = clipDownloadDurations.filter((value) => clipUploadDurations.includes(value));\n\n return {\n [ExportOptionDirectDownload]: clipDownloadDurations,\n [ExportOptionAddToSavedClips]: clipUploadDurations,\n [ExportOptionDirectDownloadAddToSavedClips]: downloadAndUploadDurations\n };\n }\n\n /**\n * Retrieves thumbnail download durations.\n */\n getThumbnailDurations(): DirectDownloadAndClipsDurations {\n return {\n [ExportOptionDirectDownload]: ThumbnailsDownloadDurations,\n [ExportOptionAddToSavedClips]: null,\n [ExportOptionDirectDownloadAddToSavedClips]: null\n };\n }\n\n /**\n * The list of speeds for which the customer can set.\n * Must be overridden.\n */\n @computed('camera')\n get availableSpeeds(): number[] {\n throw new Error('availableSpeeds must be overridden.');\n }\n\n /**\n * This tracks the SVR and Camera Player id currently playing audio.\n */\n @tracked oeAudioInfo: OEAudioInfo | null = null;\n\n /**\n * Available durations (in seconds) from which a user may pick for clip downloads.\n * Must be overridden.\n */\n get allPossibleClipDownloadDurations(): number[] {\n throw new Error('allPossibleClipDownloadDurations must be overridden.');\n }\n\n /**\n * Available durations (in seconds) from which a user may pick for clip uploads.\n * Must be overridden.\n */\n get allPossibleClipUploadDurations(): number[] {\n throw new Error('allPossibleClipUploadDurations must be overriden.');\n }\n\n // endregion Abstract Functions and Properties.\n\n // region Functions.\n\n /**\n * Gets the video source and reloads it if necessary.\n */\n async getVideoSource(deviceId: string, shouldReload: boolean): Promise {\n const { videoSourceEndpoint } = this,\n camera = this.getCamera(deviceId);\n\n if (!camera) {\n return null;\n }\n\n const existingVideoSource = (videoSourceEndpoint ? await camera.get(videoSourceEndpoint) : null) as\n | SvrVideoSource\n | SdCardVideoSource\n | null;\n\n if (!existingVideoSource && this.videoSourceModelPath) {\n return await this.store.findRecord(this.videoSourceModelPath, camera.id, { reload: true });\n }\n\n if (existingVideoSource && shouldReload) {\n const streamingProperties = await reloadVideoSource.call(this, existingVideoSource, {\n forceProxy: this.forceProxyFromQueryParam\n });\n\n // TODO VID-80442 These properties were set previously in reloadVideoSource but weren't type checked.\n // Now that they are set outside of the method, TS (probably correctly) complains.\n // This method is probably not the right one - we may just want to use getFreshVideoSource.\n // @ts-expect-error: Please replace the above call with getFreshVideoSource and thoroughly check edge cases with loading.\n streamingProperties && setProperties(this, streamingProperties);\n }\n\n return existingVideoSource;\n }\n\n /**\n * Returns scrubber thumbnail URL.\n */ // eslint-disable-next-line no-unused-vars\n async getScrubberThumbnailUrl(deviceId: string): Promise {\n const camera = this.getCamera(deviceId);\n\n if (!camera) {\n return Promise.resolve();\n }\n\n const existingEndpoint = (await camera.get(this.scrubberThumbnailEndpoint || '')) as\n | SvrThumbnailEndpoint\n | SdCardThumbnailEndpoint;\n\n // TODO: This ignore is an existing deprecation that must be refactored, do not copy this usage\n // eslint-disable-next-line @adc/ember/no-is-destroyed\n return isDestroyed(this) ? null : existingEndpoint.url;\n }\n\n /**\n * Update the player with the newly selected device.\n *\n * @param cameraItems An array of camera objects to search from.\n */\n doSelectionChange(cameraItems: CameraItem[]) {\n const { playbackControl } = this;\n\n playbackControl.resetPlaybackButtons(this.model.cameras);\n\n this.playbackStateControllers = null;\n\n // Reset the coverage.\n this.resetIntervals(false, IntervalSetting.Normal);\n\n // Update properties about the scrubber thumbnails,\n // including the number to display in the timeline\n // and their aspect ratios.\n this.setScrubberThumbnailProperties(cameraItems);\n\n // Update the scrubber thumbnail URLs on camera selection change.\n this.setScrubberThumbnailUrlsDebounced(cameraItems);\n }\n\n /**\n * Get translation.\n */\n getLocalTranslation(key: string): string {\n return this.intl.t(`components.video.video-player.playback-features.${key}`);\n }\n\n /**\n * Further component specific processing to do after camera items have been set.\n *\n * @override\n */\n afterCameraItemsProcessing(): void {\n const { cameraItems, isOperatorSite } = this;\n\n cameraItems.forEach((cameraItem) => {\n const cameraGlobalDeviceId = cameraItem.model?.globalDeviceId || '';\n\n cameraItem.player = {\n playerId: 'playback_features_' + cameraGlobalDeviceId,\n deviceId: cameraGlobalDeviceId\n };\n });\n\n // If the component is rendered on an operator page and there is only one camera selected\n // or available, hide the camera name from the timeline (collapse timeline)\n if (isOperatorSite) {\n this.collapsedModeForTimeline = cameraItems.length === 1;\n }\n\n this.resetPlayerStates();\n this.doSelectionChange(cameraItems);\n\n // If the camera items are changed, stop their audio.\n this.oeAudioInfo = null;\n }\n\n /**\n * Resets player states depending on whether or not they are visible.\n */\n resetPlayerStates(): void {\n // Initialize player states.\n this.activeCameras?.forEach((activeCamera) => {\n const deviceId = activeCamera.globalDeviceId;\n const isCameraDisplayed = deviceIdMatchesSelectedDevices(deviceId || '', this.cameraItems);\n const playerState = isCameraDisplayed ? INITIALIZING_STATE : NOT_VISIBLE_STATE;\n this.playbackControl.updatePageAndPlayerState(playerState, deviceId || '', this.activeCameras);\n });\n }\n\n /**\n * Clears the intervals, resets them, and prepares playback.\n *\n * @param hardResetSource Should fresh source data be retrieved rather than attempting to look up the videoSource from the cache?\n * @param resetIntervalsSetting Setting for handling how intervals should be reset.\n * @param cameraItems\n * An array of camera objects. Will be null when useVideoStreamingPlayers=false.\n * @param [successCallback] The function to call if coverage was reset successfully.\n *\n * @returns {Promise|void}\n */\n async resetIntervals(\n hardResetSource: boolean,\n resetIntervalsSetting: number,\n successCallback = () => {}\n ): Promise {\n const {\n cameraItems,\n initialStreamDataLoaded,\n intervalsControl,\n playbackInfoCacheManager,\n playerType,\n playbackControl,\n deviceIdsDisplayingOnPage\n } = this;\n\n if (!cameraItems || !cameraItems.length || !cameraItems[0].model || !playerType) {\n return;\n }\n\n const intervalsFromCacheInfo = intervalsControl.getIntervalsFromCacheIfNeeded(\n resetIntervalsSetting,\n deviceIdsDisplayingOnPage,\n initialStreamDataLoaded\n );\n\n if (!intervalsFromCacheInfo) {\n return;\n }\n\n const cachedAllStreamsIntervals = intervalsFromCacheInfo.allStreamsIntervals;\n\n if (!hardResetSource && cachedAllStreamsIntervals.length) {\n const allStreamsIntervals = await this.getAndAddMissingIntervalsToAllStreamsIntervals(\n cachedAllStreamsIntervals,\n intervalsFromCacheInfo.forceLoadFreshIntervals\n );\n\n // Set the current time to the user's most recent values if we have them.\n const { timelineStartTime, timelineEndTime, currentTime } =\n playbackInfoCacheManager.getPlaybackTimesFromCache(deviceIdsDisplayingOnPage, playerType);\n\n if (!this.handleIntervalsLoadMotionPreparePlayback(allStreamsIntervals)) {\n return;\n }\n\n if (currentTime) {\n playbackControl.setTimelineTimes(timelineStartTime, timelineEndTime);\n this.updateCurrentTime(currentTime);\n }\n\n // Wait a cycle to prevent pageState from being modified twice in one render, which causes app-error.\n // Do not copy this deprecated usage. If you see this, please fix.\n // eslint-disable-next-line ember/no-runloop\n next(() => successCallback());\n return allStreamsIntervals;\n }\n\n this.loadingStreamInformation = true;\n this.resetPlayerStates();\n\n const allStreamsIntervals = await intervalsControl.getIntervals(\n cameraItems,\n intervalsFromCacheInfo.forceLoadFreshIntervals,\n this.getVideoSource.bind(this)\n );\n\n const handlePrepareResult = this.handleIntervalsLoadMotionPreparePlayback(allStreamsIntervals);\n\n if (!handlePrepareResult) {\n // this if statement only fails if the context is destroyed\n if (handlePrepareResult === false) {\n this.onSetIntervalsFailed();\n }\n return;\n }\n\n // Wait a cycle to prevent pageState from being modified twice in one render, which causes app-error.\n // Do not copy this deprecated usage. If you see this, please fix.\n // eslint-disable-next-line ember/no-runloop\n next(() => successCallback());\n }\n\n /**\n * Set time and date properties based on the intervals that were retrieved.\n *\n * @param allStreamsIntervals The interval data for all streams that were retrieved from the API call.\n *\n * @returns False if intervals data is empty or if all players have errors.\n */\n handleIntervals(allStreamsIntervals: AllStreamsIntervals): boolean {\n const {\n avsDataObject,\n cameraItems,\n intervalsControl,\n isLoginRestrictedFromLiveVideo,\n lockTimelineBoundsToAvailableVideo,\n isOperatorSite,\n getVideoSource,\n visualVerification,\n playbackControl\n } = this,\n { timelineStartTime, timelineEndTime } = playbackControl,\n { earliestPlaybackTimeUtc } = intervalsControl;\n\n if (!timelineStartTime || !timelineEndTime) {\n return false;\n }\n\n this.loadingStreamInformation = false;\n\n const intervalUsabilityInfo = intervalsControl.getIntervalUsabilityAndUpdateValues(\n allStreamsIntervals,\n cameraItems,\n timelineStartTime,\n timelineEndTime,\n getVideoSource.bind(this),\n avsDataObject\n );\n\n Object.entries(intervalUsabilityInfo.errorEnumMapping).forEach(([globalDeviceId, errorEnum]) => {\n this.playbackControl.updatePageAndPlayerState(\n DISCONNECTED_STATE,\n globalDeviceId,\n this.activeCameras,\n errorEnum\n );\n });\n\n const { earliestRecordDate, foundPlayerWithoutErrors, latestRecordDate } = intervalUsabilityInfo;\n\n // We only need to call resetTimes here if this is for login as login (but not managed 24/7 access), and we haven't set the earliest playback time yet OR if we want to lock the timeline bounds to the available video.\n if (lockTimelineBoundsToAvailableVideo || (isLoginRestrictedFromLiveVideo && !earliestPlaybackTimeUtc)) {\n const newEarliestPlaybackTimeUtc = intervalsControl.getAndStoreEarliestAvailablePlaybackTime();\n\n if (newEarliestPlaybackTimeUtc) {\n // Call resetTimes with earliest/latest dates that we've extracted from the intervals to prevent it from being reset.\n if (earliestRecordDate && latestRecordDate) {\n if (lockTimelineBoundsToAvailableVideo) {\n this.changeTimeInterval(\n differenceInSeconds(latestRecordDate, newEarliestPlaybackTimeUtc),\n false\n );\n }\n this.resetTimes(earliestRecordDate, latestRecordDate);\n }\n\n // If the component is rendered from a Visual Verification page we need to update current time so that if the user clicks play once he reaches the page, it will start at the time of the latest alarm\n if (isOperatorSite && visualVerification.lastAlarmDate) {\n this.updateCurrentTime(new Date(visualVerification.lastAlarmDate));\n }\n }\n }\n\n return foundPlayerWithoutErrors && !!earliestRecordDate && !!latestRecordDate;\n }\n\n /**\n * Safely get camera object.\n */\n getCamera(globalDeviceId: string): Camera | undefined {\n // Find the camera model that matches the given device ID.\n const camera = this.model.cameras.findBy('id', globalDeviceId);\n\n // Guard against missing model.\n if (!camera) {\n const { playerTypeString } = this;\n console.warn(`No ${playerTypeString} camera retrieved for ${playerTypeString} player ${globalDeviceId}`);\n return;\n }\n\n return camera;\n }\n\n /*\n * Saves the current playback times on the page into the playback info cache manager.\n * This should only be used on playback features\n *\n * @override\n */\n savePlaybackTimesToCache(deviceIds: string[]) {\n const { playbackInfoCacheManager, playerType, playbackControl } = this,\n { timelineStartTime, timelineEndTime, currentTime } = playbackControl;\n\n playbackInfoCacheManager.addPlaybackTimesToCache(\n deviceIds,\n playerType!,\n timelineStartTime!,\n timelineEndTime!,\n currentTime!\n );\n }\n\n // endregion Functions.\n\n // region Actions.\n\n /**\n * Action to reset intervals when a new alarm occurs\n */\n @action\n onAlarmChanged() {\n this.resetIntervals(true, IntervalSetting.HardReset, this.startVideoPlayback);\n }\n\n /**\n * When the timeline or event history components indicate that the user is hovering over an event.\n *\n * @param events List of event ids hovered over from anywhere in the video timeline component.\n */\n @action\n onEventHover(events: string[]): void {\n if (!areArraysSame(events, this.highlightedEventIds)) {\n this.highlightedEventIds = events;\n }\n }\n\n /**\n * When the event-history component triggers a new filter to be applied on the page.\n *\n * @param filterFn A function that is used for filtering which events are visible on the page.\n */\n @action\n onFilterApplied(\n filterFn: (\n eventId: number,\n deviceTypeFilterIds: number[],\n ovClassification: number,\n globalDeviceId: string\n ) => boolean\n ): void {\n // filterFn will over-compute on initial page load without 'next'.\n // Do not copy this deprecated usage. If you see this, please fix.\n // eslint-disable-next-line ember/no-runloop\n next(() => {\n this.filterFn = filterFn;\n });\n }\n\n /**\n * Adds dom listener for hotkeys.\n */\n @action\n addHotKeys(): void {\n this.dom.addListener(this, document, 'keydown', (event: KeyboardEvent) =>\n this.keyDownHandlerForPlayback(event)\n );\n }\n\n // region Timeline Actions.\n\n /**\n * Handles when a new time is clicked but not yet set. A new selection call these actions in the following order:\n *
      \n *
    1. onTimelineSelectionStart
    2. \n *
    3. onTimelineUpdate
    4. \n *
    5. onTimelineNewTimeSet
    6. \n *
    \n */\n @action\n onTimelineSelectionStart(): void {\n // Stops playback so the bar and time doesn't move when we're selecting a time.\n // This should be the only time when isPlaying is set to false when the video is actually playing.\n setCameraProperties(\n this.model.cameras,\n {\n isPlaying: false\n },\n ALL_CAMERAS_ID\n );\n\n this.playbackControl.updateToFrozenStateIfValid(this.activeCameras);\n }\n\n /**\n * Handles when a new time is set while being dragged on the timeline.\n *\n * @param newTime\n * @param shouldResumePlayback if we should resume playback if currently paused\n */\n @action\n onTimelineUpdate(newTime: Date, shouldResumePlayback: boolean) {\n const { playbackControl } = this;\n\n playbackControl.updateToFrozenStateIfValid(this.activeCameras);\n\n // This is called when dragging, only the current time displayed will change and the seek won't actually be performed.\n this.updateCurrentTime(newTime);\n\n if (shouldResumePlayback) {\n this.resumeOrRetryIfNeeded(false);\n }\n }\n\n /**\n * Handles when a new time is set on the timeline.\n *\n * @param newTime The new current time.\n * @param timelineEnum The enum for differentiated whether the user clicked on the back arrow, forward arrow, or on the timeline.\n */\n @action\n onTimelineNewTimeSet(newTime: Date, timelineEnum: number): void {\n const { intervalsControl, playbackControl } = this,\n { currentTime, pageState } = playbackControl;\n\n if (!currentTime) {\n return;\n }\n\n // If this is a seek on pause, we will use that information in the onPlayStarted event.\n playbackControl.updateHasSeekedAfterPause();\n\n // Update the timeline state and visuals.\n // If video is already playing or paused, continue playing at the new time.\n this.handleNewTimeSelection(newTime, timelineEnum);\n\n // If playback hasn't started yet or is disconnected, then start or restart playback\n // when the user clicks on a part of the timeline where there is no gap.\n if (\n timelineEnum === TimelineClick &&\n [READY_STATE, DISCONNECTED_STATE].includes(pageState) &&\n currentTime &&\n !intervalsControl.getIntervalInfoForCurrentTime(currentTime).isInGap\n ) {\n this.resumeOrRetryIfNeeded(true);\n }\n }\n\n /**\n * Gives the correct interval in seconds. Called when switching between hour/day view.\n */\n @action\n changeTimeInterval(interval: number, storeCookieAndLogToWaveFront: boolean): void {\n // make sure the value actually changed\n if (interval === this.playbackControl.timeInterval) {\n return;\n }\n\n if (storeCookieAndLogToWaveFront) {\n const isDayMode = interval === NUM_SECONDS_IN_DAY;\n storeCookieForPage.call(this, COOKIE_INTERVAL, interval, false);\n logEventConditionToWavefront(this.stats, PLAYBACK_INTERVAL, isDayMode);\n }\n\n this.playbackControl.setTimeInterval(interval);\n }\n\n /**\n * When the time interval value changes, lets update the timeline to reflect that\n */\n @action\n onTimeIntervalChange(): void {\n const { playbackControl } = this,\n { currentTime, timeInterval, timelineStartTime, timelineEndTime } = playbackControl;\n\n if (!currentTime || !timelineEndTime || !timelineStartTime || !timeInterval) {\n return;\n }\n\n // We want to make sure that the cursor is in the same position after the interval change.\n // timelineEndTime and timelineStartTime can't be the same, so we don't have to worry about division by 0.\n const datePercentage =\n differenceInMilliseconds(currentTime, timelineStartTime) /\n differenceInMilliseconds(timelineEndTime, timelineStartTime);\n\n // The new current time is not in the current interval, we must adjust the interval appropriately.\n this.updateTimelineAndLoadThumbnailsAndEvents(\n subSeconds(currentTime, Math.round(timeInterval * datePercentage))\n );\n }\n\n /**\n * Periodically synchronizes the time between the client and the video player.\n *\n * @param newOffset The time which the video player is reporting.\n */\n @action\n onSyncTimer(newOffset: number): void {\n const { playbackControl } = this,\n { currentTime, hasSeekedAfterPause, initialSeekForPlaySeconds } = playbackControl;\n\n // If the component is destroyed, or we have seeked after pausing,\n // then we don't want to try to sync the timeline scrubber with the stream.\n // Note: if we try to sync the timeline scrubber immediately after seeking during a pause,\n // the scrubber will jitter back to the old time while the stream resumes and tries to catch up the with the seek request.\n // TODO: This ignore is an existing deprecation that must be refactored, do not copy this usage\n // eslint-disable-next-line @adc/ember/no-is-destroyed\n if (isDestroyed(this) || hasSeekedAfterPause || !currentTime) {\n return;\n }\n\n // Adjust the start time based on initial seek so that we are correctly placing the scrubber.\n const adjustedStartTime = addSeconds(currentTime, initialSeekForPlaySeconds),\n newCurrentTime = addMilliseconds(adjustedStartTime, newOffset);\n\n this.moveToNextAvailableStartTime(newCurrentTime);\n }\n\n /**\n * Sets time and date properties after the coverage info is set but before playback starts.\n */\n @action\n preparePlayback(): void {\n const { camerasDataObject, intervalsControl, playbackControl, useHdStream } = this,\n { timeInterval } = playbackControl,\n { latestRecord } = intervalsControl.getData();\n let { currentTime } = playbackControl;\n\n // this should never happen but need these checks for TS to be happy\n if (!currentTime || !timeInterval || !latestRecord) {\n return;\n }\n\n // We have to take care of an edge case where the current time ends up matching latestRecord.\n // We want to start in the middle in this case.\n if (isEqual(currentTime, latestRecord) || isAfter(currentTime, latestRecord)) {\n currentTime = subSeconds(latestRecord, timeInterval / 2);\n }\n\n if (!this.moveToNextAvailableStartTime(currentTime)) {\n return;\n }\n\n // Get the current time again because it might have changed from moveToNextAvailableStartTime\n currentTime = playbackControl.currentTime;\n\n if (!currentTime) {\n return;\n }\n\n this.playbackControl.handlePlaybackPrepared(\n useHdStream,\n camerasDataObject,\n intervalsControl.getDataForTime(currentTime)\n );\n }\n\n /**\n * Toggles the visibility of the date picker.\n */\n @action\n toggleDatePicker(): void {\n const { playbackControl, intervalsControl, modals } = this,\n { currentTime } = playbackControl,\n { allStreamsIntervals, earliestRecord, latestRecord } = intervalsControl;\n\n logEventConditionToWavefront(this.stats, PLAYBACK_DATE_PICKER, true);\n\n if (!allStreamsIntervals) {\n return;\n }\n\n // Close modal if opened already.\n if (modals.modalIsOpen(DateTimePickerModal)) {\n modals.closeModal(false);\n return;\n }\n\n const coveredDays = new Set();\n allStreamsIntervals.forEach((stream) => {\n stream.intervals?.forEach(({ startTime, endTime }) => {\n eachDayOfInterval({ start: startTime, end: endTime }).forEach((day) => {\n coveredDays.add(day.getTime());\n });\n });\n });\n\n // If no stream has coverage for the date, disable that date (return true).\n const disableDate = (date: Date) => {\n return !coveredDays.has(startOfDay(date).getTime());\n },\n model = {\n // If there is no earliest record or latest record, then just the current time.\n // This will limit the modal's date range.\n minDate: earliestRecord || currentTime,\n maxDate: latestRecord || currentTime,\n defaultDate: currentTime,\n disableDate,\n onSelection: this.onSelection\n };\n\n modals.showModal(DateTimePickerModal, model);\n }\n\n /**\n * Toggles whether we should show the collapsed timeline display mode.\n */\n @action\n toggleCollapsedModeForTimeline(): void {\n const { collapsedModeForTimeline } = this;\n\n logEventConditionToWavefront(this.stats, PLAYBACK_EXPAND_COLLAPSE_TIMELINE, !collapsedModeForTimeline);\n this.collapsedModeForTimeline = !collapsedModeForTimeline;\n\n storeCookieForPage.call(this, COOKIE_USE_COLLAPSED_TIMELINE, !collapsedModeForTimeline, false);\n }\n\n /**\n * Toggles whether we should hide or show the event-history sidebar.\n *\n * @param closedFromSidebar If this action was triggered from the X button on the sidebar\n * (otherwise from the button on the timeline).\n */\n @action\n toggleHideSidebar(closedFromSidebar: boolean, isEventHistory: boolean): void {\n const { hideSidebar, sidebarToggleHasBeenUsed, usingEventHistorySidebar } = this;\n\n if (!sidebarToggleHasBeenUsed) {\n this.sidebarToggleHasBeenUsed = true;\n\n // If this is the first time the user has interacted with the sidebar,\n // and their first interaction is closing the sidebar with the X button inside the sidebar,\n // then we want to flash the sidebar button in the timeline so that they know where it is if they want to re-open it.\n if (closedFromSidebar) {\n this.sidebarButtonIsFlashing = true;\n setTimeout(() => {\n // TODO: This ignore is an existing deprecation that must be refactored, do not copy this usage\n // eslint-disable-next-line @adc/ember/no-is-destroyed\n if (isDestroyed(this)) {\n return;\n }\n\n this.sidebarButtonIsFlashing = false;\n }, SidebarButtonFlashingMilliseconds);\n }\n }\n\n logEventConditionToWavefront(this.stats, PLAYBACK_SIDEBAR_OPEN_CLOSE, !hideSidebar);\n storeCookieForPage.call(this, COOKIE_HIDE_SIDEBAR, !hideSidebar, false);\n this.hideSidebar = !hideSidebar;\n\n // if we're switching from one sidebar to the other, we animate one closed and then animate the other open\n if (!hideSidebar && isEventHistory !== usingEventHistorySidebar) {\n this.switchSidebarTask.perform();\n return;\n }\n\n this.usingEventHistorySidebar = isEventHistory;\n }\n\n // endregion Timeline Actions.\n\n // region Playback Actions.\n\n /**\n * Performs the necessary actions when playback has started.\n */\n @action\n onPlayStarted(globalDeviceId: string): void {\n const { camerasDataObject, playbackControl } = this;\n\n playbackControl.handleOnPlayStarted(camerasDataObject, globalDeviceId);\n }\n\n /**\n * Action for when players have errored out.\n */\n @action // eslint-disable-next-line @typescript-eslint/no-unused-vars\n onError(globalDeviceId: string, _playerId: string, _errorInfo: string) {\n this.onPlayEnded(globalDeviceId, false, false);\n }\n\n /**\n * Performs the necessary actions when playback has ended.\n * This gets triggered when switching between cameras (since the current stream has to stop) and when the player has an error.\n *\n * @param globalDeviceId The global device id on the camera model.\n * @param isTimeout Is this due to a natural timeout?\n * @param isEndOfStream Is this due to reaching the end of the timeline?\n */\n @action\n onPlayEnded(globalDeviceId: string, isTimeout: boolean, isEndOfStream: boolean): void {\n const { activeCameras, cameraItems, camerasDataObject, intervalsControl, playbackControl } = this,\n { currentTime } = playbackControl;\n\n if (!currentTime) {\n return;\n }\n\n const playerState = activeCameras?.findBy('id', globalDeviceId)?.playerState,\n intervalInfo = intervalsControl.getIntervalInfoForCurrentTime(currentTime);\n\n let streamError = NoError;\n\n // Make sure the playEnded matches a device on the screen.\n // (It is possible for this event to fire right after switching groups.)\n if (deviceIdMatchesSelectedDevices(globalDeviceId, cameraItems)) {\n streamError = PlaybackStreamConnectionFailed;\n // For network disconnections, the player will go into a frozen state before disconnecting\n if (playerState === FROZEN_STATE) {\n streamError = StreamDisconnected;\n } else if (playerState === PLAYING_STATE) {\n if (isTimeout) {\n // If it's a natural/real timeout.\n streamError = PlaybackStreamTimeout;\n } else if (isEndOfStream || intervalInfo.isInGap) {\n streamError = PlaybackEnded;\n } else {\n // Otherwise it was disconnected while connecting to stream (meaning camera lost connection during playback).\n streamError = StreamDisconnected;\n }\n\n setCameraProperties(\n this.activeCameras,\n {\n hasStreamTimedOut: isTimeout,\n hasReachedEndOfStream: isEndOfStream\n },\n globalDeviceId\n );\n } else if (this.shouldForceEndToEndWithExtendedTimeouts) {\n streamError = StunReconnectionFailed;\n\n // If it's the last failed player on the SVR timeline, reset the force flag.\n if (getCamerasCountInState(this.cameraItems, LOADING_STATE) === 1) {\n this.shouldForceEndToEndWithExtendedTimeouts = false;\n }\n }\n }\n\n if (streamError !== NoError) {\n playbackControl.handleDisconnectedPlaybackPlayer(streamError, globalDeviceId, camerasDataObject);\n }\n\n // If playback has ended, set the `oeAudioInfo` to null to clear the related audio UI elements.\n this.oeAudioInfo = null;\n }\n\n /**\n * Pauses playback on the player.\n */\n @action\n pause(): void {\n this.playbackControl.pause(this.camerasDataObject);\n }\n\n /**\n * Seeks to a time in the video.\n *\n * @param offset The offset from the starting time of the video to seek to.\n * @param seekEnum The enum that should be reported to WaveFront to differentiate seeking back and seeking forward.\n */\n @action\n seek(offset: number, seekEnum: number): void {\n const { playbackControl } = this,\n { currentTime } = playbackControl;\n\n if (!currentTime) {\n return;\n }\n\n logEventConditionToWavefront(this.stats, PLAYBACK_SEEK, offset > 0);\n playbackControl.updateHasSeekedAfterPause();\n\n const newTime = addSeconds(currentTime, offset);\n this.handleNewTimeSelection(newTime, seekEnum, undefined, true);\n }\n\n /**\n * Sets the new speed for playback.\n */\n @action\n onSpeedChange(newSpeed: string | number): void {\n this.playbackControl.onSpeedChange(newSpeed, this.availableSpeeds, this.camerasDataObject, this.useHdStream);\n }\n\n /**\n * Resets video source information and gets fresh recording intervals to restart the stream.\n */\n @action\n refreshVideoSource(globalDeviceId: string): void {\n const { camerasDataObject, playbackInfoCacheManager, playbackControl, useHdStream } = this;\n\n playbackControl.refreshVideoSource(\n globalDeviceId,\n camerasDataObject,\n useHdStream,\n playbackInfoCacheManager,\n this.getVideoSource.bind(this)\n );\n }\n\n /**\n * Moves the currentTime to the next available start time outside any gaps,\n * or goes into Disconnected state if playback has reached the end of available video.\n *\n * @param fromTime The time to use for calculating the next start time. Uses currentTime if no value is passed in.\n *\n * @returns True if there is a valid next start time, or false if there is no available video after currentTime.\n */\n @action\n moveToNextAvailableStartTime(fromTime: Date | null = null): boolean {\n const { avsDataObject, camerasDataObject, intervalsControl, playbackControl } = this,\n { currentTime, initStarted, seekTypeEnum } = playbackControl,\n time = fromTime || currentTime;\n\n if (!time || !currentTime) {\n return false;\n }\n\n const { nextAvailableTimeAction, nextVideoAvailableAt } = intervalsControl.determineNextAvailableTimeAction(\n time,\n !!avsDataObject,\n initStarted,\n seekTypeEnum\n );\n\n if (nextVideoAvailableAt) {\n switch (nextAvailableTimeAction) {\n case NextAvailableTimeAction.HandleNewTime:\n playbackControl.setSeekTypeEnum(AutoSkipGap);\n this.handleNewTimeSelection(nextVideoAvailableAt);\n return true;\n case NextAvailableTimeAction.UpdateCurrentTime:\n this.updateCurrentTime(nextVideoAvailableAt);\n return true;\n }\n }\n\n switch (nextAvailableTimeAction) {\n case NextAvailableTimeAction.DisconnectNoPlayback:\n playbackControl.disconnectNoPlaybackAvailable(camerasDataObject);\n return false;\n case NextAvailableTimeAction.DisconnectPlaybackEnded:\n playbackControl.disconnectPlaybackEnded(camerasDataObject);\n return false;\n case NextAvailableTimeAction.ResetIntervalsAndResume:\n this.resetIntervals(false, IntervalSetting.Normal, () => this.resumeOrRetryIfNeeded(false));\n return false;\n }\n\n return false;\n }\n\n /**\n * Resets all the time properties to their default values.\n * This is used in init() and when changing cameras from the dropdown,\n * so that the timeline is not based off the previous camera that was selected.\n * This is also called in handleIntervals() to reset the timeline for login-as-login,\n * using the earliest available playback time found from the intervals.\n * The optional parameters are for LAL to provide in values that would otherwise be reset completely.\n */\n @action\n resetTimes(earliestRecordDate?: Date, latestRecordDate?: Date): void {\n const { intervalsControl, playbackControl } = this;\n\n const resetTimeValues = intervalsControl.getResetTimeValues(playbackControl.timeInterval);\n\n if (!resetTimeValues) {\n return;\n }\n\n playbackControl.setTimelineTimes(resetTimeValues.timelineStartTime, resetTimeValues.timelineEndTime);\n intervalsControl.setEarliestAndLatestRecords(\n earliestRecordDate || resetTimeValues.timelineStartTime,\n latestRecordDate || resetTimeValues.timelineEndTime\n );\n\n this.updateCurrentTime(resetTimeValues.newCurrentTime);\n }\n\n /**\n * Sets the autoPlayWhenReady value to the isPlaying value\n */\n @action\n setAutoPlayWhenReady() {\n this.playbackControl.setAutoPlayWhenReady();\n }\n\n /**\n * Toggles the stream resolution between HD and standard.\n */\n @action\n toggleHD(): void {\n const { camerasDataObject, playbackControl, useHdStream } = this,\n { pageState } = playbackControl;\n this.send('toggleStreamResolution');\n\n // Before playback starts and the playback state controllers are set, setWebRtcPlayerUrls treats\n // apex streams like WebRTC streams, which breaks playback for apex streams\n if (![INITIALIZING_STATE, READY_STATE].includes(pageState)) {\n playbackControl.setPlayerUrlsForAllCameraItems(camerasDataObject, useHdStream);\n }\n }\n\n /**\n * Updates the page to a new time and then loads thumbnails and events\n */\n @action\n updateCurrentTime(newTime: Date) {\n this.playbackControl.updateCurrentTime(\n newTime,\n this.intervalsControl.getData(),\n this.updateTimelineAndLoadThumbnailsAndEvents.bind(this)\n );\n }\n\n /**\n * Updates the timeline to the new timeline start time selected and then loads scrubber thumbnails and events (if needed)\n */\n @action\n updateTimelineAndLoadThumbnailsAndEvents(newTimelineStartTime: Date): void {\n const timelineStartTimeChanged = this.playbackControl.updateTimeline(\n newTimelineStartTime,\n this.intervalsControl.earliestRecord,\n this.intervalsControl.latestRecord\n );\n\n this.savePlaybackTimesToCache(this.deviceIdsDisplayingOnPage);\n\n // If we're looking at a new time range, let's load event history to see if any new events appear in the new times.\n if (timelineStartTimeChanged) {\n this.loadEventHistoryAndMotionIntervals();\n }\n\n // Update the scrubber thumbnail URL, so that we get the correct thumbnails for this new timeline start/end times.\n this.setScrubberThumbnailUrlsDebounced(this.cameraItems);\n }\n\n // endregion Playback Actions.\n\n // region Activity Event Actions.\n\n /**\n * Performs a seek to the time of the event on the timeline.\n *\n * @param isFromTimeline Is this event being initiated from the timeline?\n * @param event The event which we should seek to.\n */\n @action\n goToEvent(isFromTimeline: boolean, event: HistoryEvent): void {\n logEventConditionToWavefront(this.stats, TIMELINE_EVENT_POPOVER, isFromTimeline);\n\n // For the events that have a clip thumbnail (aka snapshot)\n // associated with them, the thumnailTimestamp indicates a point in time\n // when the \"action happens\", i.e. a person is detected.\n // When we seek to an event in a timeline, we should prefer thumbnailTimestamp over the\n // eventDate, so we don't land before or after the action actually taking place.\n const eventDate = event.thumbnailTimestamp ?? event.eventDate,\n newTime = subSeconds(eventDate, EventOffset);\n\n this.handleNewTimeSelection(newTime, ActivityEvent, true, true);\n }\n\n /**\n * Seek to new time and update the visuals and state.\n *\n * @param shouldResume if we should start playback even if the page is currently in a paused state\n * @param seekEvenIfPaused if we should seek even if the page is in a paused state\n */\n @action\n handleNewTimeSelection(newTime: Date, seekEnum?: number, shouldResume?: boolean, seekEvenIfPaused?: boolean): void {\n const { camerasDataObject, intervalsControl, playbackControl, useHdStream } = this;\n\n playbackControl.updateToFrozenStateIfValid(camerasDataObject.activeCameras);\n\n if (seekEnum) {\n playbackControl.setSeekTypeEnum(seekEnum);\n }\n\n this.updateCurrentTime(newTime);\n\n if (!seekEvenIfPaused && playbackControl.isTimelineButtonDisplayingPlayIcon) {\n return;\n }\n\n playbackControl.setLoadStartTimeAndPlaybackRestartedForWavefrontLogging();\n\n // Getting currentTime here because updateCurrentTime may have modified it\n const { currentTime } = playbackControl;\n\n if (!currentTime) {\n return;\n }\n\n if (shouldResume) {\n this.resumeOrRetryIfNeeded(false);\n return;\n }\n\n playbackControl.seekToCurrentTime(camerasDataObject, intervalsControl.getDataForTime(currentTime), useHdStream);\n }\n\n /**\n * This wrapper action function is used in the template so other shared components can make requests to reload event history.\n */\n @action\n loadEventHistory(): void {\n // Clone the start and end times, so they can be compared later.\n const { playbackControl } = this,\n { timelineStartTime, timelineEndTime } = playbackControl;\n\n if (!timelineStartTime || !timelineEndTime) {\n return;\n }\n\n try {\n const startTime = timelineStartTime.toISOString(),\n endTime = timelineEndTime.toISOString();\n\n // for some reason NEXT seems to be needed, otherwise this.events can be changed twice in the same cycle\n // Do not copy this deprecated usage. If you see this, please fix.\n // eslint-disable-next-line ember/no-runloop\n next(async () => {\n // empty out the events so that the timeline/sidebar know to show loading indicators until the new events are loaded\n this.events = null;\n\n this.events = await this.store\n .query('activity/history-event', {\n startTime,\n endTime,\n filter: PlaybackPagesEventHistoryItems,\n includeCommands: false,\n getThumbnails: true\n })\n .then((events) => events.sortBy('eventDate'));\n });\n } catch (ex) {\n sentryWithScopeAndError('Unable to load event history', {\n ex,\n timelineStartTime,\n timelineEndTime\n });\n }\n }\n\n /**\n * Action function that runs whenever the camera order in the video streaming player changes\n */\n @action\n onSwapCamera() {\n // eslint-disable-next-line ember/no-assignment-of-untracked-properties-used-in-tracking-contexts\n this.cameraItems = this.cameraItems.sortBy('viewIndex');\n this.setScrubberThumbnailProperties(this.cameraItems);\n this.setScrubberThumbnailUrlsDebounced(this.cameraItems);\n }\n\n // endregion Activity Event Actions.\n\n // region Player Overlay Actions.\n\n /**\n * Opens the export clip modal.\n */\n @action\n openExportClipModal(deviceId: string): void {\n logEventConditionToWavefront(this.stats, DOWNLOAD_CLIP, false);\n this.openExportModal(deviceId, this.clipDownloadModalComponent, this.getClipDurations(deviceId), true);\n }\n\n /**\n * Opens the export thumbnail modal.\n */\n @action\n openDownloadThumbnailsModal(deviceId: string): void {\n logEventConditionToWavefront(this.stats, DOWNLOAD_CLIP, true);\n this.openExportModal(deviceId, this.thumbnailsDownloadModalComponent, this.getThumbnailDurations(), false);\n }\n\n /**\n * Resume playback, or retry if disconnected (during a user action)\n *\n * @param isUserResumeAction if this is triggered from a user resume action. (if false it might be because its triggered by a new time select action)\n * When triggered from a user resume action, we log a play event and retry the connection if disconnected\n */\n @action\n resumeOrRetryIfNeeded(isUserResumeAction: boolean): void {\n const { camerasDataObject, intervalsControl, playbackControl, useHdStream } = this,\n { currentTime } = playbackControl;\n\n // If the players are disconnected during a user resume action, retry the connection.\n // because seeking/playing after it has disconnected won't work.\n if (isUserResumeAction && playbackControl.pageState === DISCONNECTED_STATE) {\n this.retryConnection(ALL_CAMERAS_ID);\n return;\n }\n\n if (!currentTime) {\n return;\n }\n\n playbackControl.resumePlayback(\n useHdStream,\n camerasDataObject,\n intervalsControl.getDataForTime(currentTime),\n isUserResumeAction\n );\n }\n\n /**\n * If the camera times out, retry the connection upon clicking the 'retry' button.\n */\n @action\n retryConnection(globalDeviceId: string): void {\n const { camerasDataObject, deviceIdsDisplayingOnPage, playbackControl } = this;\n\n playbackControl.retryConnection(\n globalDeviceId,\n deviceIdsDisplayingOnPage,\n camerasDataObject,\n this.resetIntervals.bind(this, true, IntervalSetting.HardReset, this.startVideoPlayback)\n );\n }\n\n /**\n * Starts video playback based on the current parameter on the page.\n */\n @action\n startVideoPlayback() {\n const { camerasDataObject, intervalsControl, playbackControl, useHdStream } = this,\n { currentTime } = playbackControl;\n\n if (!currentTime) {\n return;\n }\n\n playbackControl.startVideoPlayback(\n true,\n useHdStream,\n camerasDataObject,\n intervalsControl.getDataForTime(currentTime)\n );\n }\n\n /**\n * Updates the state of the timer\n */\n @action\n updatePageControls() {\n const { camerasDataObject, intervalsControl, playbackControl } = this,\n { currentTime } = playbackControl;\n\n if (!currentTime) {\n return;\n }\n\n this.playbackControl.updatePageControls(camerasDataObject, intervalsControl.getDataForTime(currentTime));\n }\n\n /**\n * Changes the state of the camera selected.\n */\n @action\n updatePageAndPlayerState(newState: number, globalDeviceId: string) {\n this.playbackControl.updatePageAndPlayerState(newState, globalDeviceId, this.activeCameras);\n }\n\n /**\n * Sets the loading percentage for the camera selected.\n */\n @action\n setLoadingPercentage(loadingPercentage: number, globalDeviceId: string) {\n setCameraProperties(\n this.model.cameras,\n {\n loadingPercentage\n },\n globalDeviceId\n );\n }\n\n /**\n * Saves a snapshot from a specific time from the camera to the customer's computer.\n */\n @action\n saveSnapshot(camera: Camera, buttonAnimation: Promise): Promise {\n return this.savePlaybackSnapshotTask.perform(buttonAnimation, camera);\n }\n\n // endregion Player Overlay Actions.\n\n // region Toolbar Actions.\n\n /**\n * Handles a user clicking a button to go to the previous or next page.\n * @override\n */\n @action\n changePage(newPage: number): void {\n this.setAutoPlayWhenReady();\n set(this, 'page', newPage);\n this.layoutControl.setExpandedCameraIndex(undefined);\n this.playbackControl.setSeekTypeEnum(PageChange);\n\n this.updatePage && this.updatePage(newPage);\n }\n\n // endregion Toolbar Actions.\n\n // region Redirect Actions.\n\n /**\n * Handles the transition to the AddVideoDevice page.\n */\n @action\n goToAddNewVideoDevice(): void {\n this.navigation.transitionToRouteId(VideoAddNewDevice);\n }\n\n // endregion Redirect Actions.\n\n // region Rendering Actions.\n\n /**\n * Process the loaded model data.\n */\n @action\n dataLoaded({\n cameraGroups,\n cameras,\n videoStreamingPermissions,\n groupResolution,\n locationCameraGroupInfos\n }: {\n cameraGroups: CameraGroup[];\n cameras: Camera[];\n dewarpConfigs: ArrayProxy;\n videoStreamingPermissions: VideoStreamingPermissionsCollection;\n groupResolution: number;\n locationCameraGroupInfos: LocationModel[];\n }): void {\n const { autoViewMaxVideosPerPageLimit, layoutControl } = this;\n this.hasVideoAnalyticsReadAccess = videoStreamingPermissions.hasVideoAnalyticsReadAccess;\n this.hasAttributeSearch = videoStreamingPermissions.hasAttributeSearch;\n\n const sortedCameraGroups = cameraGroups ? cameraGroups.sortBy('order') : [];\n\n addLocationGroupsToCameraGroups.call(this, locationCameraGroupInfos, sortedCameraGroups, cameras);\n\n if (!cameras.length) {\n return;\n }\n\n layoutControl.makeSureLayoutIsSetCorrectly(cameras.length, false);\n\n set(this, 'cameraGroups', sortedCameraGroups);\n set(this, 'cameras', cameras);\n this.canEditCameraGroups = videoStreamingPermissions.canEditCameraGroups;\n this.canViewManageCameraGroups = videoStreamingPermissions.canViewManageCameraGroups;\n set(this, 'moreThanOneSupportedCamera', cameras.length > 1);\n set(this, 'useHdStream', groupResolution === Highest);\n set(layoutControl, 'maxVideosPerPageAutoView', autoViewMaxVideosPerPageLimit);\n\n updateCameraGroupAndCamera.call(this, sortedCameraGroups, cameras);\n setInitialSetupDone.call(this);\n }\n\n /**\n * Switches to either the next or previous AVS video\n */\n @action\n goToAdjacentAvsVideo(isForward: boolean): void {\n const { avsDataObject } = this;\n\n if (!avsDataObject) {\n return;\n }\n\n const { searchResults, selectedResultIndex } = avsDataObject;\n\n if (!searchResults || selectedResultIndex == null) {\n return;\n }\n\n const newIndex = isForward ? selectedResultIndex + 1 : selectedResultIndex - 1,\n searchResult = searchResults[newIndex];\n\n if (!searchResult) {\n return;\n }\n\n this.changeSelectedAvsResult(newIndex);\n this.onTimelineNewTimeSet(searchResult.startTime, TimelineClick);\n }\n\n /**\n * Navigates to the AVS search page.\n */\n @action\n goToAvsSearch(cameraId: string): void {\n const { contextManager, playbackControl } = this,\n { timeInterval, timelineStartTime, timelineEndTime } = playbackControl;\n\n const advancedVideoSearchRoute = contextManager.isEnterprise\n ? EmberEnterpriseVideoAdvancedVideoSearch\n : EmberVideoAdvancedVideoSearch;\n\n // TODO: This ignore is an existing deprecation that must be refactored, do not copy this usage\n // eslint-disable-next-line @adc/ember/no-context-manager-transition\n contextManager.transitionToRouteId(\n advancedVideoSearchRoute,\n { startDate: timelineStartTime?.toISOString(), endDate: timelineEndTime?.toISOString(), timeInterval },\n undefined,\n cameraId\n );\n }\n\n /**\n * Navigates to the thumbnail search page\n */\n @action\n goToThumbnailSearch(cameraId: string): void {\n const { navigation, playbackControl, isSdCardComponent } = this,\n { currentTime } = playbackControl;\n\n const thumbnailSearchPage = getContextAwareThumbnailSearchPage(this.identityManager.isEnterprise);\n\n navigation.transitionToRouteId(thumbnailSearchPage, cameraId, {\n queryParams: { time: currentTime?.toISOString(), isSdCard: isSdCardComponent }\n });\n }\n\n /**\n * A wrapper for all the did-insert modifier actions being called.\n */\n @action\n insertedViewWrapper(): void {\n this.addHotKeys();\n\n // Necessary to move focus away from the page's tab button and to the app-content (a div),\n // so the space hotkey can work for playback.\n this.contextManager.focusOnAppContent();\n }\n\n /**\n * Handler for when the sidebar is resized.\n */\n @action\n onSidebarResize(): void {\n const { layoutControl } = this;\n\n // TODO: This ignore is an existing deprecation that must be refactored, do not copy this usage\n // eslint-disable-next-line @adc/ember/no-is-destroyed\n if (isDestroyed(this)) {\n return;\n }\n\n // calling updatePlayersDimensions so that transitions when hiding/showing the sidebar look smooth.\n layoutControl.updatePlayersDimensions(this.activeCameras, this.autoViewLayoutOptions, this.showPagination);\n }\n\n /**\n * Action for setting whether we are using the default filter.\n */\n @action\n onUsingDefaultFilterStatusChange(usingDefaultFilter: boolean): void {\n // usingDefaultFilter will over-compute on initial page load without 'next'.\n // Do not copy this deprecated usage. If you see this, please fix.\n // eslint-disable-next-line ember/no-runloop\n next(() => {\n this.usingDefaultFilter = usingDefaultFilter;\n });\n }\n\n /**\n * Resizes the video player component to the desired dimensions.\n *\n * @param el The resized element.\n */\n @action\n resizeVideoPlayers(el: HTMLDivElement): void {\n const { layoutControl } = this;\n\n // TODO: This ignore is an existing deprecation that must be refactored, do not copy this usage\n // eslint-disable-next-line @adc/ember/no-is-destroyed\n if (isDestroyed(this)) {\n return;\n }\n\n const activities = el.querySelector('.event-history'),\n players = el.querySelector('.players');\n\n if (activities && players) {\n // We have to tell the player the exact size of the container.\n // The player will handle the height and width calculations to maintain the same aspect ratio.\n this.dynamicVideoPlayerDimensions = {\n height: activities.clientHeight,\n width: players.clientWidth\n };\n }\n\n layoutControl.updatePlayersDimensions(this.activeCameras, this.autoViewLayoutOptions, this.showPagination);\n }\n\n /**\n * Deletes the players control commands for the camera provided\n */\n @action\n deletePlayersControlCommands(cameraIndex: number) {\n this.playbackControl.deletePlayersControlCommands(cameraIndex);\n }\n\n /**\n * Helper method to enable calling actions in the super class.\n */\n @action\n sendAction(name: string, ...args: any[]) {\n // Only pass along this action if the component isn't destroyed OR this is a logging WebRTC call,\n // which doesn't require the component to still be rendered to be called.\n // TODO: This ignore is an existing deprecation that must be refactored, do not copy this usage\n // eslint-disable-next-line @adc/ember/no-is-destroyed\n if (!isDestroyed(this) || (name === 'webRtcEvent' && args?.[0] === Log)) {\n this.actions[name].call(this, ...args);\n }\n }\n\n /**\n * Action for handling when a new date is selected from the datetime picker.\n */\n @action\n onSelection(selectedDate: Date) {\n const { playbackControl } = this,\n { currentTime } = playbackControl;\n\n // Don't do anything if the date didn't change.\n if (!selectedDate || selectedDate.getTime() === currentTime?.getTime()) {\n return;\n }\n\n logEventConditionToWavefront(this.stats, PLAYBACK_DATE_PICKER, false);\n playbackControl.setSeekTypeEnum(DateTimePicker);\n this.handleNewTimeSelection(selectedDate);\n\n playbackControl.setTimelineBoundsToMidnight();\n this.loadEventHistoryAndMotionIntervals();\n }\n\n /**\n * Updates the players control commands for the camera provided\n */\n @action\n updatePlayersControlCommands(cameraIndex: null | number, commandFunctions: VoidFunction[]): void {\n this.playbackControl.updatePlayersControlCommands(cameraIndex, commandFunctions);\n }\n\n // endregion Rendering Actions.\n\n // endregion Actions.\n\n /**\n * Updates component property.\n */\n @action\n updateShouldForceEndToEndWithExtendedTimeouts(newShouldForce: boolean): void {\n this.shouldForceEndToEndWithExtendedTimeouts = newShouldForce;\n }\n\n /**\n * Waits SidebarAnimationMilliseconds and then re-opens the sidebar with the opposite one showing\n */\n switchSidebarTask: Task = task({ drop: true }, async () => {\n await timeout(SidebarAnimationMilliseconds);\n this.hideSidebar = !this.hideSidebar;\n this.usingEventHistorySidebar = !this.usingEventHistorySidebar;\n });\n\n /**\n * Downloads a playback snapshot at the current scrubber's timestamp to the user's computer.\n */\n savePlaybackSnapshotTask = task(\n { restartable: true },\n async (buttonAnimation: Promise, camera: Camera) => {\n const showErrorMessage = (): AppNotification | undefined =>\n this.notificationManager.addError(this.intl.t('generic.video.failedToGetSnapshot'));\n\n const player = getPlayerByDeviceId(camera.id, this.cameraItems);\n\n if (!player) {\n showErrorMessage();\n return;\n }\n\n buttonAnimation.then(() => {\n set(player, 'showPopover', false);\n });\n\n set(player, 'showPopover', true);\n\n const fnThrowError = async (): Promise => {\n showErrorMessage();\n await timeout(FailureIconTimeoutMilliseconds);\n set(player, 'showPopover', false);\n };\n\n try {\n if (!this.scrubberThumbnailUrls) {\n await fnThrowError();\n return;\n }\n\n const snapshotEndpoint = this.scrubberThumbnailUrls.find((item) => item.globalDeviceId === camera.id);\n if (!snapshotEndpoint) {\n await fnThrowError();\n return;\n }\n\n const snapshotTimestamp = this.playbackControl.currentTime?.toISOString();\n if (!snapshotTimestamp) {\n await fnThrowError();\n return;\n }\n\n await downloadCrossOriginImage(\n `${snapshotEndpoint.url}&start=${snapshotTimestamp}&isScrubberThumbnail=false`,\n this.intl.t('generic.video.savedSnapshotName', {\n cameraName: camera.description,\n // Replace colons : with unicode character U+A789, which can be saved in file names unlike standard colons.\n currentDate: this.intl\n .formatDateTz(snapshotTimestamp, {\n format: 'shortDateTimeFormat'\n })\n .replace(/\\//g, '-')\n .replace(/:/g, '꞉')\n })\n );\n } catch (error) {\n await fnThrowError();\n }\n }\n );\n\n /**\n * Gets intervals for devices displayed on the page and appends them to the passed in allStreamsIntervals\n */\n private async getAndAddMissingIntervalsToAllStreamsIntervals(\n oldAllStreamsIntervals: AllStreamsIntervals,\n forceLoadFreshIntervals: boolean\n ): Promise {\n const { deviceIdsDisplayingOnPage, intervalsControl } = this;\n\n const missingDeviceIds = deviceIdsDisplayingOnPage.filter((id) =>\n oldAllStreamsIntervals.every((interval) => interval.globalDeviceId !== id)\n );\n let missingAllStreamsIntervals: AllStreamsIntervals = [];\n if (missingDeviceIds.length) {\n const missingCameraItems = this.cameraItems.filter(\n (cameraItem) => cameraItem.model && missingDeviceIds.includes(cameraItem.model.id)\n );\n missingAllStreamsIntervals = await intervalsControl.getIntervals(\n missingCameraItems,\n forceLoadFreshIntervals,\n this.getVideoSource.bind(this)\n );\n }\n\n return [...oldAllStreamsIntervals, ...missingAllStreamsIntervals];\n }\n\n /**\n * handles intervals, loads motion intervals, and prepares playback\n * returns boolean if the process succeeded or failed, undefined if the context is destroyed\n */\n private handleIntervalsLoadMotionPreparePlayback(allStreamsIntervals: AllStreamsIntervals): boolean | void {\n const { cachedCameraItemParameters, initialStreamDataLoaded, intervalsControl, startTime } = this;\n // TODO: This ignore is an existing deprecation that must be refactored, do not copy this usage\n // eslint-disable-next-line @adc/ember/no-is-destroyed\n if (isDestroyed(this)) {\n return;\n }\n\n if (!intervalsControl.intervalsDataMatchesDisplayedCams(allStreamsIntervals, cachedCameraItemParameters)) {\n return false;\n }\n\n if (!this.handleIntervals(allStreamsIntervals)) {\n return false;\n }\n\n // Calling to load the motion intervals after we've handled the normal intervals.\n this.loadMotionIntervals();\n\n if (!initialStreamDataLoaded) {\n this.initialStreamDataLoaded = true;\n\n if (startTime && !isNaN(Date.parse(startTime))) {\n this.handleNewTimeSelection(new Date(startTime));\n }\n }\n\n this.preparePlayback();\n\n return true;\n }\n\n /**\n * Loads the events and motion intervals for the particular timeline period (generally this is called when we switch time periods).\n */\n private loadEventHistoryAndMotionIntervals(): void {\n this.loadMotionIntervals();\n this.loadEventHistory();\n }\n\n /**\n * Keydown event handler which is added to the document on didInsert.\n */\n private keyDownHandlerForPlayback(event: KeyboardEvent): void {\n const { target, keyCode, shiftKey } = event;\n const { avsDataObject, playbackControl } = this;\n\n // If the target node already handles keyboard input or the timeline is hidden\n if (\n (target && nodeHandlesKeyboardInput(target as Node)) ||\n eventFiredWithModifier(event) ||\n avsDataObject?.svrTimelineIsHidden\n ) {\n return;\n }\n\n // This is called separately because we want it to work while modals are open to close the modal.\n // The date picker is disabled when this page is used in a Visual Verification context\n if (!this.isOperatorSite && keyCode === D_KEY) {\n this.toggleDatePicker();\n return;\n }\n\n if (this.modals.modalsToRender.length) {\n return;\n }\n\n const { speedIndex } = this.playbackControl;\n\n switch (keyCode) {\n case EQUALS_KEY:\n this.onSpeedChange(1);\n break;\n case SPACE_KEY:\n if (this.disablePlayPauseButton || nodeHandlesSpaceOrEnterInput(target as Node)) {\n return;\n }\n\n playbackControl.isTimelineButtonDisplayingPlayIcon ? this.resumeOrRetryIfNeeded(true) : this.pause();\n break;\n case LEFT_ARROW_KEY:\n // Shift plus arrows is for switching pages, so lets only seek if this wasnt pressed with shift\n if (!shiftKey) {\n this.seek(-30, SeekBack);\n }\n\n break;\n case RIGHT_ARROW_KEY:\n // Shift plus arrows is for switching pages, so lets only seek if this wasnt pressed with shift\n if (!shiftKey) {\n this.seek(30, SeekForward);\n }\n\n break;\n case LEFT_BRACKET_KEY:\n if (speedIndex === 0) {\n return;\n }\n\n this.onSpeedChange(this.availableSpeeds[speedIndex - 1]);\n break;\n case RIGHT_BRACKET_KEY:\n if (speedIndex === this.availableSpeeds.length - 1) {\n return;\n }\n\n this.onSpeedChange(this.availableSpeeds[speedIndex + 1]);\n break;\n }\n }\n\n /**\n * Opens given export component modal.\n *\n **/\n private async openExportModal(\n deviceId: string,\n modalComponentPath: ModalComponent | null,\n downloadAndUploadDurations: DirectDownloadAndClipsDurations,\n isClipDownload: boolean\n ): Promise {\n const { model, intervalsControl, playbackControl } = this,\n { currentTime, timelineEndTime } = playbackControl,\n { earliestRecord, latestRecord } = intervalsControl || {};\n\n if (!currentTime || !timelineEndTime) {\n return;\n }\n\n const player = getPlayerByDeviceId(deviceId, this.cameraItems),\n startTime = intervalsControl?.nextVideoAvailableAt(currentTime),\n clipExportOptions = this.getClipExportOptions(deviceId);\n\n if (!startTime || !player) {\n console.error('Invalid start time selected for download or player object could not be retrieved');\n return;\n }\n\n set(player, 'showPopover', false);\n setCameraProperties(\n this.activeCameras,\n {\n forceShowOverlayForExport: false\n },\n deviceId\n );\n // If we are within the current timeline range, then visually update the timeline bar.\n if (!isEqual(startTime, currentTime) && !isAfter(startTime, timelineEndTime)) {\n playbackControl.updateToFrozenStateIfValid(this.activeCameras);\n this.updateCurrentTime(startTime);\n }\n\n const properties = {\n minDate: earliestRecord,\n maxDate: latestRecord,\n defaultDate: startTime,\n cameras: model.cameras,\n defaultCamera: model.cameras.find((item) => get(item, 'id') === deviceId),\n durations: downloadAndUploadDurations,\n disableCameraSelection: true,\n exportOptions: isClipDownload ? clipExportOptions : []\n };\n\n if (modalComponentPath === null) {\n return;\n }\n\n this.modals.showModal(modalComponentPath, properties);\n }\n\n /**\n * Sets the number of minutes between scrubber thumbnails on the timeline\n * depending on the camera.\n */\n private setScrubberThumbnailProperties(cameraItems: CameraItem[]): void {\n const { playerType } = this;\n\n if (!playerType) {\n return;\n }\n\n this.scrubberThumbnailProperties = cameraItems.map((cameraItem) => {\n return {\n minutesBetweenThumbnails: cameraItem.model?.streamUsageToScrubberThumbnailsMapping?.[playerType],\n aspectRatio: cameraItem.model?.forcedAspectRatio,\n globalDeviceId: cameraItem.model?.globalDeviceId\n };\n });\n }\n\n /**\n * Sets scrubber thumbnail URL as needed.\n */\n private async setScrubberThumbnailUrls(cameraItems: CameraItem[]): Promise {\n const scrubberThumbnailUrls: ScrubbedThumbnailUrls = [];\n\n await Promise.all(\n cameraItems.map(async (cameraItem) => {\n if (!cameraItem.model?.globalDeviceId) {\n return;\n }\n\n const globalDeviceId = cameraItem.model.globalDeviceId;\n const thumbnailUrl = await this.getScrubberThumbnailUrl(globalDeviceId);\n\n scrubberThumbnailUrls.push({ url: thumbnailUrl || '', globalDeviceId });\n })\n );\n\n this.scrubberThumbnailUrls = scrubberThumbnailUrls;\n }\n\n /**\n * Debounces the call to setScrubberThumbnailUrls() so that multiple requests aren't queued simultaneously.\n */\n private setScrubberThumbnailUrlsDebounced(cameraItems: CameraItem[]): void {\n const { timelineChangeDebounceTimeMs } = this;\n // Do not copy this deprecated usage. If you see this, please convert to ember-lifeline debounceTask.\n // eslint-disable-next-line ember/no-runloop\n debounce(this, this.setScrubberThumbnailUrls, cameraItems, timelineChangeDebounceTimeMs);\n }\n}\n","import { precompileTemplate } from \"@ember/template-compilation\";\nexport default precompileTemplate(\"{{#if this.isLoading}}\\n \\n{{else}}\\n \\n <:warning>\\n \\n \\n\\n <:options-above>\\n \\n \\n\\n <:options-below>\\n \\n\\n {{#if this.selectedCamera.isOnvifCamera}}\\n
    \\n \\n

    \\n {{this.appendAdditionalTimestampMessage}}\\n

    \\n
    \\n {{/if}}\\n\\n {{#if this.supportsAudioForProxyStream}}\\n \\n {{/if}}\\n\\n {{#if (and this.svr.supportsDownscaledDownloads @model.defaultCamera.supports4MPStreaming)}}\\n \\n {{/if}}\\n\\n {{#if this.isClipDownload}}\\n \\n {{/if}}\\n \\n\\n <:above-footer-section>\\n {{#if this.vlcMessageResource}}\\n
    \\n {{safe-html this.vlcMessageResource}}\\n
    \\n {{/if}}\\n \\n \\n{{/if}}\",{ moduleName: \"customer-site/components/modals/video/download-clip/svr/index.hbs\" })","/* import __COLOCATED_TEMPLATE__ from './index.hbs'; */\nimport { tracked } from '@glimmer/tracking';\nimport { computed, get, action } from '@ember/object';\nimport { reads } from '@ember/object/computed';\nimport { inject as service } from '@ember/service';\nimport { convertResolutionToPixelCount } from 'customer-site/classes/video/clips/helpers/video-resolution-helper';\nimport { ARM } from 'customer-site/enums/ApexCpuArchitectureEnum';\nimport { SVR } from 'customer-site/enums/ClipExportType';\nimport { getSvrClipDownloadUrl, uploadSvrVideoClip } from 'customer-site/models/video/devices/camera';\nimport { HighStreamId } from 'customer-site/video/settings/camera/video-config/third-party-stream/base-third-party-stream-controller';\nimport { intlPath } from '@adc/i18n/path';\nimport ClipDownloadModal from '../base-export';\n\nimport './_style.scss';\nimport type ADCIntlService from '@adc/i18n/services/adc-intl';\nimport type Store from '@ember-data/store';\nimport type Camera from 'customer-site/models/video/devices/camera';\nimport type Svr from 'customer-site/models/video/devices/svr';\nimport type ContextManager from 'customer-site/services/context-manager';\nimport type { ClipExportModel, BaseVideoClipExportModalArgs } from '../base-export';\nimport './_style.scss';\n\nexport interface SvrClipDownloadModalArgs extends Omit {\n model: ClipExportModel;\n disableControls?: boolean;\n}\n\nexport const ENABLE_TIMESTAMPS_SECONDS = 900;\nexport const EIGHT_MP_PIXEL_COUNT = 8294400;\n\n/**\n * @classdesc\n * Displays a modal date time picker object with options for svr clip download.\n */\n@intlPath({ path: 'modals/video/download-clip/svr' })\nexport default class SvrClipDownloadModal extends ClipDownloadModal {\n @service declare store: Store;\n @service declare contextManager: ContextManager;\n @service declare intl: ADCIntlService;\n\n clipExportType = SVR;\n\n isDownscaledVideo = false;\n\n @reads('clipDownloader.svrDownloadTaskInfo.isRunning')\n declare isDownloadTaskRunning: boolean;\n\n @reads('clipUploader.svrUploadTaskInfo.isRunning')\n declare isUploadClipTaskRunning: boolean;\n\n // should we include audio when downloading this clip\n @tracked includeAudio = false;\n\n // Should we append an additional timestamp to this clip?\n @tracked shouldAppendAdditionalTimestamp = false;\n\n /**\n * Does this stream have a resolution greater than eight megapixels?\n */\n @tracked streamResolutionGreaterThanEightMegaPixels = false;\n\n /**\n * Are we still waiting for the SVR Clip Download Modal to load?\n */\n @tracked isLoading = true;\n\n /**\n * Fetch the stream settings for this device and use them to determine whether an HQ\n * stream resolution higher than eight megapixels is being used.\n *\n * @param deviceId\n */\n async fetchStreamSettings(deviceId: string) {\n const streamSettings = await this.store.query('video/stream-setting', { id: deviceId });\n\n this.streamResolutionGreaterThanEightMegapixels = streamSettings\n .toArray()\n .some(\n (setting) =>\n setting.streamId == HighStreamId &&\n convertResolutionToPixelCount(setting.resolution) > EIGHT_MP_PIXEL_COUNT\n );\n }\n\n constructor(owner: unknown, args: SvrClipDownloadModalArgs) {\n super(owner, args);\n\n if (this.selectedCamera?.isOnvifCamera) {\n this.fetchStreamSettings(this.selectedCameraId);\n }\n\n this.isLoading = false;\n }\n\n @action requestDownloadUrls(): Promise<{ value: string }> {\n return getSvrClipDownloadUrl(\n this.ajax,\n this.selectedCameraId,\n this.selectedDateTime ?? this.args.model.defaultDate ?? new Date(),\n this.duration,\n this.isDownscaledVideo,\n this.includeAudio,\n this.shouldAppendAdditionalTimestamp\n );\n }\n\n /**\n * Does the SVR support audio for proxy stream?\n */\n @reads('selectedCamera.svrVideoSource.supportsAudioForProxyStream')\n declare supportsAudioForProxyStream: boolean;\n\n /**\n * Is the device a windows device?\n */\n @reads('contextManager.identityModel.isWindowsDevice')\n declare isWindowsDevice: boolean;\n\n /**\n * Is this SVR on the ARM CPU architecture and is the camera stream greater than eight megapixels?\n */\n get isArmSvrWithStreamGreaterThanEightMegapixels(): boolean {\n return this.streamResolutionGreaterThanEightMegapixels && this.selectedCamera?.apexSvrCpuArchitecture === ARM;\n }\n\n /**\n * Should the Append Additional Timestamps checkbox be disabled?\n *\n * @note we disable the ability to append additional timestamps for streams that are either too long or too high-resolution.\n */\n get shouldDisableAdditionalTimestampsCheckbox(): boolean {\n return this.duration > ENABLE_TIMESTAMPS_SECONDS || this.isArmSvrWithStreamGreaterThanEightMegapixels;\n }\n\n /**\n * Helper method for determining which message should be displayed under the\n * Append Additional Timestamps checkbox.\n */\n get appendAdditionalTimestampMessage(): string {\n if (this.isArmSvrWithStreamGreaterThanEightMegapixels) {\n return this.intl.tc(this, 'optionNotAvailableForHighResolution');\n }\n\n return this.duration > ENABLE_TIMESTAMPS_SECONDS\n ? this.intl.tc(this, 'optionNotAvailableForLongExports')\n : this.intl.tc(this, 'exportWithTimestampsWillTakeLonger');\n }\n\n @computed('selectedCameraId', 'args.model.cameras')\n get selectedCamera(): Camera | undefined {\n return this.args.model.cameras.find((item) => get(item, 'id') === this.selectedCameraId);\n }\n\n @computed('selectedCamera.svrVideoSource.svr')\n get svr(): Svr | null {\n const { selectedCamera } = this;\n\n // DO NOT COPY THIS, PLEASE IMPLEMENT THE SUGGESTION AND TEST.\n // @ts-expect-error This code should be replaced with: `return selectedCamera ? await (await selectedCamera.svrVideoSource).svr : null;`.\n return selectedCamera ? get(get(selectedCamera, 'svrVideoSource'), 'svr') : null;\n }\n\n @computed('selectedCamera', 'isWindowsDevice')\n get vlcMessageResource(): string {\n if (!this.isWindowsDevice) {\n return '';\n }\n\n const { selectedCamera } = this;\n if (!(selectedCamera && get(get(selectedCamera, 'svrVideoSource'), 'isHighEfficiencyRecording'))) {\n return '';\n }\n\n return this.intl.tc(this, 'vlcMessage', {\n vlcLink:\n 'https://www.videolan.org/vlc/'\n });\n }\n\n @action uploadVideoClips(): Promise<{ metaData: { UploadClipStatus: boolean } }> {\n return uploadSvrVideoClip(\n this.ajax,\n this.selectedCameraId,\n this.selectedDateTime ?? this.args.model.defaultDate ?? new Date(),\n this.duration,\n this.isDownscaledVideo,\n this.shouldAppendAdditionalTimestamp,\n this.includeAudio\n );\n }\n\n /**\n * Given an input duration value, updates the duration and Append Additional Timestamp checkbox status.\n *\n * @param duration\n */\n @action handleDurationChange(duration: number) {\n this.duration = duration;\n\n if (duration > ENABLE_TIMESTAMPS_SECONDS) {\n this.shouldAppendAdditionalTimestamp = false;\n }\n }\n\n /**\n * Update duration according to export option.\n * @param newExportOption\n */\n @action updateDuration(newExportOption: number) {\n const { durations } = this.args.model;\n this.selectedExportOption = newExportOption;\n // First duration as default selection.\n this.duration = durations[newExportOption][0];\n }\n}\n","import { isDestroyed } from '@adc/ember-utils/utils/ember-helpers';\nimport { computed, setProperties, set } from '@ember/object';\nimport { getOwner } from '@ember/owner';\nimport SvrClipDownloadModal from 'customer-site/components/modals/video/download-clip/svr/index';\nimport { getOrCreateOespControllerWithUpdate } from 'customer-site/components/video/video-streaming/video-streaming-features/index';\nimport { StreamUsage } from 'customer-site/enums/StreamUsage';\nimport { WebRTC, OESP } from 'customer-site/enums/WebStreamingPlayer';\nimport { getSVRStreamingParameters } from 'customer-site/models/video/devices/camera';\nimport WebRtcProxyPlaybackStateController from '@adc/video-player/classes/state-controllers/webrtc-proxy-playback-state-controller';\nimport PlaybackFeatures, { ExportOptionAddToSavedClips, ExportOptionDirectDownloadAddToSavedClips } from '../index';\n\nimport type OespPlaybackStateController from '@adc/video-player/classes/state-controllers/oesp-playback-state-controller';\nimport type Owner from '@ember/owner';\nimport type Svr from 'customer-site/models/video/devices/svr';\nimport type { PlayerInfo } from '../../../video-streaming/video-streaming-features/types';\n\n/**\n * Finds the apex-connection-info from parts of the ajax response.\n * Returns a matching OESP playback state controller and ApexChannelGuid.\n */\nfunction getOespControllerAndChannelGuid(\n this: SvrPlaybackFeatures,\n apexConnectionRelationship: { id: string; type: string },\n fetchedRelationships: any[] // Please put an actual type here\n): { apexChannelGuid: string; controller: OespPlaybackStateController } | null {\n const { id, type } = apexConnectionRelationship;\n\n let apexConnectionInfo;\n\n // Find apexConnectionInfo starting from the end because it'll come last.\n for (let index = fetchedRelationships.length - 1; index >= 0; index--) {\n const { attributes, id: currentId, type: currentType } = fetchedRelationships[index];\n\n if (currentId === id && currentType === type) {\n apexConnectionInfo = attributes;\n break;\n }\n }\n\n if (!apexConnectionInfo?.apexId) {\n return null;\n }\n\n const oespControllerUpdateResult = getOrCreateOespControllerWithUpdate(\n getOwner(this) as Owner,\n this.playbackStateControllers || [],\n apexConnectionInfo,\n false,\n this.forcedStreamingMethod\n );\n this.playbackStateControllers = oespControllerUpdateResult.playbackStateControllers;\n return {\n apexChannelGuid: apexConnectionInfo.apexChannelGuid,\n controller: oespControllerUpdateResult.controller\n };\n}\n\n/**\n * @classdesc\n *\n * Playback features for SVR players.\n */\nexport default class SvrPlaybackFeatures extends PlaybackFeatures {\n /** @override */\n playerType = StreamUsage.Svr;\n\n /** @override */\n playerTypeString = 'SVR';\n\n /** @override */\n baseResourcePath = 'components.video.video-player.playback-features.svr-playback-features.';\n\n /** @override */\n clipDownloadModalComponent = SvrClipDownloadModal;\n\n /** @override */\n scrubberThumbnailEndpoint = 'svrScrubberThumbnailEndpoint';\n\n /** @override */\n videoSourceEndpoint = 'svrVideoSource';\n\n /** @override */\n videoSourceModelPath = 'video/videoSources/svrVideoSource';\n\n /** @override */\n supportsDownloadingThumbnailsProperty = 'svrSupportsDownloadingThumbnails';\n\n /** @override */\n @computed()\n get availableSpeeds(): number[] {\n return [1, 2, 4, 8];\n }\n\n /** @override */\n get allPossibleClipDownloadDurations() {\n // The durations are in seconds.\n // 30s, 1m, 2m, 3m, 4m, 5m, 10m, 15m, 20m, 25m, 30m, 35m, 40m, 45m, 50m, 55m, 1h.\n return [30, 60, 120, 180, 240, 300, 600, 900, 1200, 1500, 1800, 2100, 2400, 2700, 3000, 3300, 3600];\n }\n\n /** @override */\n get allPossibleClipUploadDurations() {\n // The durations are in seconds.\n // 30s, 1m, 2m, 3m, 4m, 5m, 10m, 15m, 20m, 25m, 30m.\n return [30, 60, 120, 180, 240, 300, 600, 900, 1200, 1500, 1800];\n }\n\n /** @override */\n setPropsFromVideoSource(/* deviceId */) {\n return false;\n }\n\n /**\n * @override\n */\n async loadMotionIntervals(): Promise {\n const { ajax, intervalsControl, playbackControl } = this,\n { timelineStartTime, timelineEndTime } = playbackControl;\n\n intervalsControl.loadSvrMotionIntervals(ajax, timelineStartTime, timelineEndTime);\n }\n\n /** @override */\n setPlayerUrls(player: PlayerInfo, deviceId: string, currentTime: Date): Promise {\n return getSVRStreamingParameters(\n this.ajax,\n deviceId,\n currentTime,\n this.playbackControl.speed,\n this.useHdStream,\n this.moreThanOneCameraItem\n ).then((streamingParams) => {\n const { data: videoSource, included: fetchedRelationships } = streamingParams;\n\n // TODO: This ignore is an existing deprecation that must be refactored, do not copy this usage\n // eslint-disable-next-line @adc/ember/no-is-destroyed\n if (isDestroyed(this)) {\n return;\n }\n\n if (!videoSource) {\n console.warn(`Nothing retrieved for player ${deviceId}`);\n return;\n }\n\n let { proxyUrl } = videoSource.attributes;\n set(this, 'playbackStateControllers', this.playbackStateControllers || []);\n const {\n janusGatewayUrl,\n janusToken,\n iceServers,\n spsAndPpsRequired,\n proxyStreamTimeoutTime,\n coturnAddressesTuplets,\n visualVerificationRecord,\n errorEnum,\n supportsAudioForProxyStream\n } = videoSource.attributes;\n\n if (errorEnum) {\n throw {\n errorEnum,\n errorText: `errorEnum ${errorEnum} was triggered for deviceId ${deviceId}`\n };\n }\n\n const apexConnectionRelationship = videoSource.relationships?.apexConnectionInfo?.data;\n const proxyWebrtcConnectionInfoRelationship = videoSource.relationships?.proxyWebrtcConnectionInfo?.data;\n\n if (apexConnectionRelationship && fetchedRelationships) {\n const { apexChannelGuid, controller } =\n getOespControllerAndChannelGuid.call(this, apexConnectionRelationship, fetchedRelationships) ?? {};\n\n if (controller) {\n setProperties(player, {\n svrId: controller.id,\n index: controller.playerCount++,\n apexChannelGuid,\n playbackStateController: controller,\n playerType: OESP,\n attemptedDirectAndProxy: true,\n supportsAudioForProxyStream\n });\n\n return;\n }\n }\n\n // A proxyUrl may be returned for the video source, but a proxyUrl stream is not valid without a janusToken.\n // Therefore, we will empty out the URLs so that the connection fails immediately.\n // TODO: This is somewhat of a workaround fix and should be removed later. Ideally the backend would do this for us.\n if (!janusToken) {\n proxyUrl = null;\n }\n\n const { playbackStateControllers } = this;\n let controller = playbackStateControllers?.find(\n (controller) => controller instanceof WebRtcProxyPlaybackStateController\n );\n // All WebRTC players can use the same controller.\n if (!controller) {\n controller = new WebRtcProxyPlaybackStateController();\n playbackStateControllers?.push(controller);\n }\n\n setProperties(player, {\n attemptedDirectAndProxy: true,\n deviceId,\n proxyUrl,\n janusGatewayUrl,\n janusToken,\n iceServers,\n spsAndPpsRequired,\n playerUrl: proxyUrl,\n proxyStreamTimeoutTime,\n visualVerificationRecord,\n coturnAddressesTuplets,\n playbackStateController: controller,\n playerType: WebRTC,\n proxyWebrtcConnectionInfo: proxyWebrtcConnectionInfoRelationship\n });\n });\n }\n\n /** @override */\n getClipDownloadDurations(deviceId: string): number[] {\n const camera = this.getCamera(deviceId);\n if (!camera) {\n return [];\n }\n\n const cameraMaxClipDuration = camera.maxSvrClipDownloadDurationSec,\n // DO NOT COPY THIS, PLEASE IMPLEMENT THE SUGGESTION AND TEST.\n // @ts-expect-error svrVideoSource is async, so this code should be replaced with: `svr = await (await camera.svrVideoSource).svr,`.\n svr = camera.svrVideoSource.get('svr') as Svr,\n svrMaxClipDuration = svr.get('maxAllowedClipDownloadDuration');\n\n const maxClipDuration = cameraMaxClipDuration < svrMaxClipDuration ? cameraMaxClipDuration : svrMaxClipDuration;\n // Filter to the durations the SVR supports.\n return this.allPossibleClipDownloadDurations.filter((duration) => duration <= maxClipDuration);\n }\n\n /** @override */\n getClipUploadDurations(deviceId: string): number[] {\n const camera = this.getCamera(deviceId);\n if (!camera) {\n return [];\n }\n\n // Filter to the durations the SVR supports.\n return this.allPossibleClipUploadDurations.filter((duration) => duration <= camera.maxSvrClipUploadDurationSec);\n }\n\n /** @override */\n getClipExportOptions(deviceId: string): number[] {\n const camera = this.getCamera(deviceId);\n if (!camera || !camera.hasSvrSchedule || !camera.svrVideoSource) {\n return [];\n }\n const exportOptions = super.getClipExportOptions(deviceId);\n\n // DO NOT COPY THIS, PLEASE IMPLEMENT THE SUGGESTION AND TEST.\n // @ts-expect-error This code should be replaced with: `if ((await (await camera.svrVideoSource).svr).supportsVideoClipUpload && this.canUploadFrom247ToCloud) {`.\n if (camera.svrVideoSource.get('svr.supportsVideoClipUpload') && this.canUploadFrom247ToCloud) {\n exportOptions.push(ExportOptionAddToSavedClips);\n exportOptions.push(ExportOptionDirectDownloadAddToSavedClips);\n }\n return exportOptions;\n }\n}\n\ndeclare module '@glint/environment-ember-loose/registry' {\n export default interface Registry {\n 'Video::VideoPlayer::PlaybackFeatures::SvrPlaybackFeatures': typeof SvrPlaybackFeatures;\n }\n}\n","import { precompileTemplate } from \"@ember/template-compilation\";\nexport default precompileTemplate(\"
    \\n

    \\n {{@description}}\\n

    \\n

    \\n {{this.formattedDateAndTime}}\\n

    \\n
    \",{ moduleName: \"customer-site/components/video/video-streaming/video-streaming-players/operator-title/index.hbs\" })","/* import __COLOCATED_TEMPLATE__ from './index.hbs'; */\nimport Component from '@glimmer/component';\nimport { computed } from '@ember/object';\nimport { inject as service } from '@ember/service';\n\nimport './_style.scss';\nimport type ADCIntlService from '@adc/i18n/services/adc-intl';\n\ninterface OperatorTitleSignature {\n Args: {\n description: string;\n startDate: Date;\n endDate: Date;\n };\n}\n\nexport default class OperatorTitle extends Component {\n @service declare intl: ADCIntlService;\n\n /**\n * Based on 'startDate' and 'endDate', return a string in the following format:\n * 'Sep 16 | 7:00 AM - 7:30 AM' OR 'Sep 15 - Sep 16 | 23:45 PM - 00:15 AM'\n */\n @computed('intl', 'args.{startDate,endDate}')\n get formattedDateAndTime(): string {\n const { startDate, endDate } = this.args;\n const [formattedStartDate, formattedEndDate] = [startDate, endDate].map((d) =>\n this.intl.formatDateTz(d, {\n month: 'short',\n day: 'numeric'\n })\n ),\n [formattedStartTime, formattedEndTime] = [startDate, endDate].map((d) =>\n this.intl.formatDateTz(d, {\n format: 'shortTimeFormat'\n })\n );\n\n return `${formattedStartDate} ${\n formattedStartDate === formattedEndDate ? '' : '- ' + formattedEndDate\n } | ${formattedStartTime} - ${formattedEndTime}`;\n }\n}\n\ndeclare module '@glint/environment-ember-loose/registry' {\n export default interface Registry {\n 'Video::VideoStreaming::VideoStreamingPlayers::OperatorTitle': typeof OperatorTitle;\n }\n}\n","import { precompileTemplate } from \"@ember/template-compilation\";\nexport default precompileTemplate(\"\\n
    \\n \\n {{#if @avsSearchFailed}}\\n
    \\n \\n \\n
    \\n \\n
    \\n
    \\n {{else if this.isConnectedAndInGap}}\\n
    \\n \\n \\n
    \\n {{else if this.isReady}}\\n
    \\n \\n \\n
    \\n {{/if}}\\n
    \\n\",{ moduleName: \"customer-site/components/video/video-player/overlay/playback-overlay/index.hbs\" })","/* import __COLOCATED_TEMPLATE__ from './index.hbs'; */\nimport { action, computed, set } from '@ember/object';\nimport { equal, or, alias } from '@ember/object/computed';\nimport { inject as service } from '@ember/service';\nimport {\n ButtonDownload,\n ButtonPanTilt,\n ButtonDetailedOsd,\n ButtonMoreOptions,\n ButtonAdvancedVideoSearch,\n ButtonRequestRecordingAndSnapshot\n} from 'customer-site/components/video/video-player/overlay/player-buttons/index';\nimport { StreamUsage } from 'customer-site/enums/StreamUsage';\nimport { DISCONNECTED_STATE, READY_STATE, INITIALIZING_STATE } from 'customer-site/enums/VideoPlayerStateEnum';\nimport { NoPermissions, DeviceNotConnected, NoError } from 'customer-site/enums/VideoSourceError';\nimport { intlPath } from '@adc/i18n/path';\nimport BaseOverlay from '../base-overlay';\n\nimport type Camera from 'customer-site/models/video/devices/camera';\nimport type ClipDownloader from 'customer-site/services/video/clip-downloader';\nimport type { BaseVideoOverlayArgs } from '../base-overlay';\nimport './_style.scss';\nimport type { AvsSwitchAbility } from 'customer-site/components/video/video-streaming/video-streaming-players';\nimport type AjaxService from 'customer-site/services/ajax';\nimport type IdentityManager from 'customer-site/services/identity-manager';\nimport type VisualVerification from 'customer-site/services/visual-verification';\n\nexport interface CameraArgs extends Camera {\n isInGap: boolean;\n}\nexport interface PlaybackOverlayArgs extends BaseVideoOverlayArgs {\n avsResultSwitchAbility: AvsSwitchAbility;\n avsSearchFailed: boolean;\n camera: CameraArgs;\n disableTryDirectConnectionButton: boolean;\n disableVolumeButton: boolean;\n downloadClip: () => void;\n downloadThumbnails: () => void;\n goToAdjacentVideo: (isForward: boolean) => void;\n goToAvsSearch: () => void;\n goToThumbnailSearch: () => void;\n isPaused: boolean;\n playerState: number;\n playerType: StreamUsage;\n restartAvsSearch: () => void;\n resume: () => void;\n saveSnapshot?: (buttonAnimation: Promise) => void;\n supportsAdvancedVideoSearch: boolean;\n supportsClipDownload: boolean;\n supportsThumbnailsDownload: boolean;\n supportsThumbnailSearch: boolean;\n transparentBackground: boolean;\n}\n\n/**\n * @classdesc\n * The overlay for playback that fits on top of the player and displays information about the current streaming status.\n */\n@intlPath({ path: 'video/video-player/overlay/playback-overlay' })\nexport default class PlaybackOverlay extends BaseOverlay {\n @service declare ajax: AjaxService;\n @service('video.clip-downloader') declare clipDownloader: ClipDownloader;\n @service declare identityManager: IdentityManager;\n @service declare visualVerification: VisualVerification;\n\n // Overridden Properties.\n\n /** @override */\n @equal('args.errorEnum', DeviceNotConnected)\n declare showTroubleshootButton: boolean;\n\n /** @override */\n get canStreamVideo(): boolean {\n return this.args.errorEnum !== NoPermissions;\n }\n\n // endregion\n\n // region Player States.\n\n /**\n * Is the player currently ready to stream?\n *\n */\n @equal('args.playerState', READY_STATE)\n declare isReady: boolean;\n\n /**\n * Is the player currently in a gap (period without video) and is the device also not disconnected.\n *\n */\n @computed('args.camera.isInGap', 'isDisconnected')\n get isConnectedAndInGap(): boolean {\n const { camera } = this.args,\n { isDisconnected } = this,\n { isInGap } = camera || {};\n\n return !isDisconnected && isInGap;\n }\n\n /**\n * Is the player currently ready to stream?\n *\n * @returns {boolean}\n */\n @equal('args.playerState', DISCONNECTED_STATE)\n declare isDisconnected: boolean;\n\n // endregion\n\n /**\n * Is the player currently paused?\n *\n * @type {boolean}\n */\n isPaused = false;\n\n /**\n * Does this stream support clip downloading?\n *\n * @type {boolean}\n */\n supportsClipDownload = false;\n\n /**\n * Does this stream support thumbnail downloading?\n *\n * @type {boolean}\n */\n supportsThumbnailsDownload = false;\n\n /**\n * Indicates if the download popover should be connected to the download button.\n *\n * @type {boolean}\n */\n useDownloadAnchor = true;\n\n /**\n * The selector to anchor the download popover for download.\n *\n */\n @computed('args.camera.id', 'useDownloadAnchor')\n get downloadPopoverAnchorSelector(): string {\n return `#player-${this.args.camera?.id} .${this.useDownloadAnchor ? 'download' : 'more-options'}-button`;\n }\n\n /**\n * Which buttons to enable on the overlay\n *\n */\n @computed(\n 'args.{camera.inCriticalDataMode,isOeStream,supportsAdvancedVideoSearch,supportsClipDownload,supportsThumbnailsDownload,camera.svrSupportsDownloadingThumbnails,playerType}',\n 'hasDetailedOsdOption',\n 'identityManager.identityModel.isVisualVerification',\n 'visualVerification.pageFeatures.canDownloadClips'\n )\n get enabledButtons(): Array {\n const buttons = [ButtonMoreOptions],\n { supportsClipDownload, supportsThumbnailsDownload, playerType } = this.args,\n isOperatorSite = this.identityManager.identityModel?.isVisualVerification,\n canOperatorDownloadClips = this.visualVerification.pageFeatures?.canDownloadClips;\n\n if (this.args.camera.inCriticalDataMode) {\n return buttons;\n }\n\n buttons.push(ButtonPanTilt);\n\n // If is OESP stream and users has stream stats permissions (internal beta), then user can view detailed OSD\n if (this.args.isOeStream && this.hasDetailedOsdOption) {\n buttons.push(ButtonDetailedOsd);\n }\n\n if ((supportsClipDownload || supportsThumbnailsDownload) && (!isOperatorSite || canOperatorDownloadClips)) {\n buttons.push(ButtonDownload);\n\n if (playerType === StreamUsage.Svr && this.args.camera.svrSupportsDownloadingThumbnails) {\n buttons.push(ButtonRequestRecordingAndSnapshot);\n }\n }\n\n if (this.args.supportsAdvancedVideoSearch) {\n buttons.push(ButtonAdvancedVideoSearch);\n }\n\n return buttons;\n }\n\n /**\n * If the user is either hovering over or clicking on the overlay\n */\n isHoveringOrClicking = false;\n\n /**\n * The player containing attributes like playerId and showDownloadClipPopover.\n *\n * @type {Player}\n */\n player = null;\n\n /**\n * Should the overlay (bottom bar with camera information and download buttons, and swap icon) be made visible?\n *\n * @returns {boolean}\n */\n @or('isHoveringOrClicking', 'args.player.showPopover')\n declare makeOverlayVisible: boolean;\n\n /**\n * Should the clip download button be disabled?\n *\n * @returns {boolean}\n */\n get disableDownloadButton(): boolean {\n const { playerState } = this.args;\n return playerState === DISCONNECTED_STATE || playerState === INITIALIZING_STATE;\n }\n\n /**\n * Is the download task running? (Is there a clip being prepared on the backend for the user to download)\n *\n * @returns {boolean}\n */\n @alias('clipDownloader.isAnyDownloadTaskRunning')\n declare isDownloadTaskRunning: boolean;\n\n @alias('clipUploader.isUploadClipTaskRunning')\n declare isUploadClipTaskRunning: boolean;\n\n @alias('args.camera.forceShowOverlayForExport')\n declare downloadPopoverIsOpen: boolean;\n\n /** @override */\n @action reportStreamingErrorToWaveFront(): void {\n const { isDisconnected, stats } = this;\n const { errorEnum } = this.args;\n if (isDisconnected && errorEnum !== NoError) {\n stats.logPlayerError(errorEnum);\n }\n }\n\n /**\n * Show the popover for downloading a clip.\n *\n * @param {bool} useDownloadAnchor if we should anchor the popover on the download button (otherwise more options button)\n */\n @action showDownloadPopover(useDownloadAnchor: boolean): void {\n set(this, 'useDownloadAnchor', useDownloadAnchor);\n set(this.args.camera, 'forceShowOverlayForExport', true);\n set(this.args.player, 'showPopover', true);\n }\n\n /**\n * Toggles the download popover visibility.\n */\n @action toggleDownloadPopover(): void {\n set(this, 'downloadPopoverIsOpen', !this.downloadPopoverIsOpen);\n }\n}\n","import { precompileTemplate } from \"@ember/template-compilation\";\nexport default precompileTemplate(\"{{! @glint-nocheck: Please convert base class to glimmer component. }}\\n\\n{{#if (eq this.playerUsage this.OESP)}}\\n {{#if (or @camera.osdOverlayEnabled this.hasDetailedOsdEnabled)}}\\n \\n {{/if}}\\n \\n \\n \\n{{else}}\\n \\n \\n \\n{{/if}}\\n{{#if @isDraggingOver}}\\n \\n{{/if}}\",{ moduleName: \"customer-site/components/video/video-player/base-playback-player/index.hbs\" })","/* import __COLOCATED_TEMPLATE__ from './index.hbs'; */\nimport { action, computed } from '@ember/object';\nimport { alias } from '@ember/object/computed';\nimport { inject as service } from '@ember/service';\nimport { type Registry as ServiceRegistry } from '@ember/service';\nimport { task } from 'ember-concurrency';\nimport { StreamUsage } from 'customer-site/enums/StreamUsage';\nimport { INITIALIZING_STATE, READY_STATE, LOADING_STATE } from 'customer-site/enums/VideoPlayerStateEnum';\nimport { NoError } from 'customer-site/enums/VideoSourceError';\nimport OespPlaybackStateController from '@adc/video-player/classes/state-controllers/oesp-playback-state-controller';\nimport { attemptProxy } from '../../../../utils/video/general';\nimport { CLEAR_MESSAGE, PAUSE, RESET, RESUME, SEEK, SET_SPEED, SHOW_MESSAGE } from '../../utils/players-control';\nimport BaseVideoPlayer from '../base-video-player';\nimport { doOnPlaybackControllers } from '../base-video-player';\n\nimport type ClipDownloader from 'customer-site/services/video/clip-downloader';\nimport type { Task } from 'ember-concurrency';\nimport type { Commands, ErrorInfo } from '../base-video-player';\n\ntype DeviceProperties = {\n firmwareVersion?: string;\n deviceModel?: string;\n};\n\ntype PlaybackStateCommandResult = {\n result: boolean;\n runControllerCommands: boolean;\n};\n\n/**\n * We can divide the flow for continuous cloud video playback into 4 states.\n *
      \n *
    1. INIT - The streams are currently initializing (eg. setting up the video streams)
    2. \n *
    3. PLAYING - The streams are currently playing.
    4. \n *
    5. PAUSED - The streams are currently paused.
    6. \n *
    7. ENDED - The streams has ended. This is the default state when the user visits a new stream.
    8. \n *
    \n */\nenum State {\n Init = 1,\n Playing = 2,\n Paused = 4,\n Ended = 8\n}\n\n/**\n * Resumes playback for all players.\n *\n * @returns Whether the resume was successful and if we should run the controller commands.\n */\nfunction resume(this: BasePlaybackPlayer): PlaybackStateCommandResult {\n return updatePlaybackStateCommand.call(this, false);\n}\n\n/**\n * Pauses playback for all players.\n *\n * @returns Whether the pause was successful and if we should run the controller commands\n */\nfunction pause(this: BasePlaybackPlayer): PlaybackStateCommandResult {\n return updatePlaybackStateCommand.call(this, true);\n}\n\n/**\n * A helper function used for pause and resume player commands.\n *\n * @param isPauseCommand True if sending pause command, and false when if resume command\n * @returns The object will hold the result of the function and if the controller command should be run.\n */\nfunction updatePlaybackStateCommand(this: BasePlaybackPlayer, isPauseCommand: boolean): PlaybackStateCommandResult {\n switch (this.state) {\n case State.Init:\n this.set('pausedOnInit', isPauseCommand);\n return {\n result: true,\n runControllerCommands: false\n };\n case State.Ended:\n return {\n result: false,\n runControllerCommands: false\n };\n default:\n this.set('state', isPauseCommand ? State.Paused : State.Playing);\n return {\n result: true,\n runControllerCommands: true\n };\n }\n}\n\n/**\n * Performs a seek for all players.\n *\n * @private\n * @instance\n * @memberOf components.video.BasePlaybackPlayer\n */\nfunction seek(this: BasePlaybackPlayer): void {\n // The player would not send the frozen event when seeking, so we have to fake it.\n // Use closure action.\n this.playFrozen && this.playFrozen();\n}\n\n/**\n * Sets the player to use a new speed.\n * @returns Whether setting the speed was successful and if we should run controller commands.\n */\nfunction setSpeed(this: BasePlaybackPlayer, speed: number): PlaybackStateCommandResult {\n if (speed == null) {\n return {\n result: false,\n runControllerCommands: false\n };\n }\n\n // The player would not send the frozen event when changing speeds, so we have to fake it.\n // Use closure action.\n this.playFrozen && this.playFrozen();\n this.set('speed', speed);\n\n return {\n result: true,\n runControllerCommands: true\n };\n}\n\n/**\n * Resets the component to its initial state.\n */\nfunction reset(this: BasePlaybackPlayer): void {\n this.setProperties({\n state: State.Ended,\n pausedOnInit: false\n });\n}\n\n/**\n * @classdesc\n *\n * Base player for continuous playback (ex. SVR, SD card, continuous cloud).\n */\nexport default class BasePlaybackPlayer extends BaseVideoPlayer {\n @service('video.clip-downloader') declare clipDownloader: ClipDownloader;\n @service declare contextManager: ServiceRegistry['context-manager'];\n\n /** @ignore */\n willDestroyElement(): void {\n reset.call(this);\n return super.willDestroyElement();\n }\n\n tagName = '';\n\n /**\n * The current state of this component.\n */\n state = State.Ended;\n\n /**\n * The current speed for playback.\n */\n speed = 1;\n\n /**\n * Whether the user has paused the stream during the initialization phase.\n */\n pausedOnInit = false;\n\n /**\n * Does this playback player support clip downloads?\n */\n supportsClipDownload = false;\n\n /**\n * Does this playback player and camera model support thumbnail downloads?\n */\n supportsThumbnailsDownload = false;\n\n /**\n * Does this camera model support thumbnail search?\n *\n * @type {boolean}\n */\n supportsThumbnailSearch = false;\n\n /**\n * Are the streaming urls encoded (and must be decoded by the flash player)?\n */\n urlEncoded = false;\n\n /**\n * The enum from base-video-player to represent the type of player (live, continuous cloud, sd card).\n */\n playerType?: number = undefined;\n\n /** @override */\n @alias('camera.connectionStartTime')\n declare connectionStartTimeForLogging: number;\n\n /**\n * The current error enum from the stream connection.\n */\n streamConnectionErrorEnum = NoError;\n\n /**\n * If this playback object ever received a playStarted message.\n */\n playStartedWasTriggered = false;\n\n /**\n * If the live snapshot has finished loading on the page.\n */\n snapshotLoaded = false;\n\n /**\n * If Advanced Video Search is enabled on the page\n */\n enableAdvancedVideoSearch?: boolean;\n\n /**\n * Action for when an error occurs\n */\n onErrorHandler?: (playerId: string, errorInfo: ErrorInfo) => void;\n\n /**\n * Action for when play ends\n */\n playEnded?: (globalDeviceId?: string, isTimeout?: boolean, isEndOfStream?: boolean) => void;\n\n /**\n * Action for when play becomes frozen\n */\n playFrozen?: () => void;\n\n /**\n * Action for when play becomes paused\n */\n playPaused?: () => void;\n\n /**\n * Action for when play starts\n */\n playStarted?: () => void;\n\n /**\n * Action to refresh the video source\n */\n refreshVideoSource?: (globalDeviceId: string) => void;\n\n /**\n * Action for setting OE audio info.\n */\n setOEAudioInfo?: (shouldMute: boolean, cameraId: string, svrId?: string) => void;\n\n /**\n * The commands to expose to the parent.\n */\n @computed('clearMessage', 'showMessage')\n get commands(): Commands {\n return [\n [SHOW_MESSAGE, this.showMessage],\n [CLEAR_MESSAGE, this.clearMessage],\n [RESUME, resume],\n [PAUSE, pause],\n [SEEK, seek],\n [SET_SPEED, setSpeed],\n [RESET, reset]\n ];\n }\n\n /**\n * returns the current firmware version based on whether the camera is an SVR\n */\n @computed(\n 'camera.svrVideoSource.svr.{deviceModel,firmwareVersion}',\n 'camera.{deviceModel,firmwareVersion}',\n 'playerType'\n )\n get deviceProperties(): Promise {\n return (async () => {\n const { camera, playerType } = this;\n let firmwareVersion, deviceModel;\n\n const resolvedCamera = await camera;\n\n if (playerType === StreamUsage.Svr) {\n const svrVideoSource = await resolvedCamera?.svrVideoSource;\n const svr = await svrVideoSource?.svr;\n\n firmwareVersion = svr?.firmwareVersion;\n deviceModel = svr?.deviceModel;\n } else {\n firmwareVersion = resolvedCamera?.firmwareVersion;\n deviceModel = resolvedCamera?.deviceModel;\n }\n\n return { firmwareVersion, deviceModel };\n })();\n }\n\n /**\n * If we should enable the link for advanced video search for this device\n */\n @computed(\n 'camera.svrVideoSource.svr.supportsAdvancedMotionSearch',\n 'contextManager.identityModel.hasInternalBetaAccess',\n 'playerType',\n 'enableAdvancedVideoSearch'\n )\n get supportsAdvancedVideoSearch(): Promise {\n return (async () => {\n const resolvedCamera = await this.camera;\n const svrVideoSource = await resolvedCamera?.svrVideoSource;\n const svr = await svrVideoSource?.svr;\n\n // On internal beta accounts we are allowing users to access the AVS page for any SVR device\n // It is a modified version of the page which doesn't use motion search\n return (\n this.playerType === StreamUsage.Svr &&\n !!this.enableAdvancedVideoSearch &&\n (this.contextManager.identityModel.hasInternalBetaAccess || !!svr?.supportsAdvancedMotionSearch)\n );\n })();\n }\n\n /**\n * If we should show the live snapshot of the stream on the page.\n */\n @computed('playerState', 'playStartedWasTriggered', 'snapshotLoaded')\n get showSnapshot(): boolean {\n const { playerState, playStartedWasTriggered, snapshotLoaded } = this;\n\n // The idea here is to only show the snapshot on the states before the user has started playback. Loading and Initializing state will always be before this,\n // however Ready state may or may not be (which is why we check the playStartedWasTriggered value). We hide on Disconnected state, as this can sometimes\n // result in overlapping error messages (as a disconnected camera may have a message on the snapshot itself).\n if (!snapshotLoaded || playStartedWasTriggered) {\n return false;\n }\n\n return [READY_STATE, LOADING_STATE, INITIALIZING_STATE].includes(playerState);\n }\n\n /**\n * Implementation of onPlayStarted for playback streams\n */\n onPlayStarted(): void {\n const { pausedOnInit } = this;\n\n if (pausedOnInit) {\n // Do not copy this deprecated usage. If you see this, please fix it\n // eslint-disable-next-line ember/classic-decorator-no-classic-methods\n this.set('state', State.Paused);\n\n // Controller functions are normally called by PlayersControl.\n // But since this function isn't, we need to call it ourselves here.\n doOnPlaybackControllers.call(this, PAUSE);\n return;\n }\n\n this.hasStreamConnected = true;\n // Do not copy this deprecated usage. If you see this, please fix it\n // eslint-disable-next-line ember/classic-decorator-no-classic-methods\n this.set('playStartedWasTriggered', true);\n // Do not copy this deprecated usage. If you see this, please fix it\n // eslint-disable-next-line ember/classic-decorator-no-classic-methods\n this.set('state', State.Playing);\n this.playStarted && this.playStarted();\n }\n\n /**\n * Implementation of onPlayPaused for BasePlaybackPlayer.\n */\n onPlayPaused(): void {\n super.onPlayPaused();\n // Use closure action.\n this.playPaused && this.playPaused();\n }\n\n /**\n * Implementation of onFrozen for ContinuousCloudPlayer.\n */\n onFrozen(playerId: string, args: { streamStuckAtFrozen?: boolean } | undefined): void {\n super.onFrozen(playerId, args);\n // TODO: We would also have to pause every other player that is not frozen, so playback and remain in sync.\n // Use closure action.\n this.playFrozen && this.playFrozen();\n }\n\n /**\n * Implementation of onPlayEnded for BasePlaybackPlayer.\n */\n onPlayEnded(\n globalDeviceId: string,\n { isTimeout, isEndOfStream }: { isTimeout?: boolean; isEndOfStream?: boolean } = {}\n ): void {\n this.attemptProxyReconnection(globalDeviceId, isTimeout, isEndOfStream);\n }\n\n /**\n * Implementation of onError.\n */\n onError(playerId: string, errorInfo: ErrorInfo = {}): void {\n super.onError(playerId, errorInfo);\n this.onErrorHandler && this.onErrorHandler(playerId, errorInfo);\n }\n\n /**\n * Implementation for onIceFailure.\n */\n onIceFailure(playerId: string): void {\n super.onIceFailure(playerId);\n\n const errorMessage = null,\n shouldRestartPlayer = false;\n\n this.onErrorHandler && this.onErrorHandler(playerId, { errorMessage, shouldRestartPlayer });\n }\n\n /**\n * Implementation on onTimeout.\n */\n onTimeout(globalDeviceId: string): void {\n this.attemptProxyReconnection(globalDeviceId, true, false);\n }\n\n /** @override */\n attemptProxyReconnection(globalDeviceId: string, isTimeout?: boolean, isEndOfStream?: boolean): void {\n const { player } = this;\n\n if (!attemptProxy.call(player, player, player?.attemptedDirectAndProxy)) {\n this.playEnded && this.playEnded(globalDeviceId, isTimeout, isEndOfStream);\n }\n }\n\n /** @override */\n initializeVideoSource: Task = task({}, async (globalDeviceId: string) => {\n this.hasStreamConnected = false;\n this.refreshVideoSource && this.refreshVideoSource(globalDeviceId);\n });\n\n /**\n * Observes the url passed to the player. Once the url is passed in, the initialization phase begins.\n */\n @action\n onUrlUpdate(): void {\n const { player } = this;\n\n if (player && player.playerUrl) {\n // Do not copy this deprecated usage. If you see this, please fix it\n // eslint-disable-next-line ember/classic-decorator-no-classic-methods\n this.set('state', State.Init);\n return;\n }\n\n // Do not copy this deprecated usage. If you see this, please fix it\n // eslint-disable-next-line ember/classic-decorator-no-classic-methods\n this.set('state', State.Ended);\n this.playEnded && this.playEnded();\n }\n\n /**\n * When the live snapshot has rendered on the page.\n */\n @action\n onSnapshotLoaded(): void {\n // Do not copy this deprecated usage. If you see this, please fix it\n // eslint-disable-next-line ember/classic-decorator-no-classic-methods\n this.set('snapshotLoaded', true);\n }\n\n /**\n * Handles a user clicking the button to mute the audio coming from the camera\n * and adjusting the volume slider to change the volume of the audio coming from the camera.\n *\n * @param shouldMute Is the new state of camera audio muted?\n * @param volume The new camera audio volume value.\n * @param isEnabledAutomaticallyAfterDelay Is the camera audio being enabled automatically after a delay?\n * @param cameraWasAutoMuted if the camera was automuted. We must automute cameras because SVRs only support audio from one camera at a time.\n * @param oeSVRShouldMuteAudio If an SVR is muted. We must mute all cameras connected to that SVR to ensure consistency to accounts with one SVR.\n */\n @action changeCameraAudio(\n shouldMute: boolean,\n volume: number,\n isEnabledAutomaticallyAfterDelay = false,\n cameraWasAutoMuted = false,\n oeSVRShouldMuteAudio = false\n ): Promise {\n return (async () => {\n if (this.player?.playbackStateController instanceof OespPlaybackStateController) {\n const resolvedCamera = await this.camera;\n\n if (!resolvedCamera) {\n return;\n }\n\n // If this camera was auto-muted and it was on the same SVR, we can return because audio has been switched to the new pane\n if (cameraWasAutoMuted && !oeSVRShouldMuteAudio) {\n return;\n }\n\n this.player.playbackStateController?.changeCameraAudio(\n shouldMute,\n volume,\n isEnabledAutomaticallyAfterDelay,\n this.player?.index?.toString()\n );\n\n // if camera was automuted, don't set it as the player playing audio\n if (!cameraWasAutoMuted) {\n this.setOEAudioInfo?.(shouldMute, resolvedCamera.id, this.player?.svrId);\n }\n\n return;\n }\n\n this.player?.playbackStateController?.changeCameraAudio(\n shouldMute,\n volume,\n isEnabledAutomaticallyAfterDelay,\n this.player.playerId\n );\n })();\n }\n}\n\ndeclare module '@glint/environment-ember-loose/registry' {\n export default interface Registry {\n 'Video::VideoPlayer::BasePlaybackPlayer': typeof BasePlaybackPlayer;\n }\n}\n","import { precompileTemplate } from \"@ember/template-compilation\";\nexport default precompileTemplate(\"{{! @glint-nocheck: This component doesn\\'t seem to have it\\'s arguments defined, so we can\\'t enable glint until that is fixed. }}\\n
    \\n {{#if @showCameraItems}}\\n {{#each @cameraItems as |cameraItem index|}}\\n {{!-- During drag-drop, we make the cameraItem being dragged over invisible now, unless the drag over index is the same as the drag origin index.\\n The idea here is that we dont want to make a user think something has been \\\"dropped\\\" until they actually release the mouse (even though it actually has) --}}\\n {{#let (and (eq cameraItem.viewIndex this.draggingOverIndex) (not this.isDraggingOverOrigin)) as |makePlayerInvisible|}}\\n {{#if this.showOperatorTitle}}\\n \\n {{/if}}\\n
    \\n {{#if @isLiveView}}\\n \\n {{else}}\\n \\n {{/if}}\\n
    \\n {{/let}}\\n {{/each}}\\n {{/if}}\\n
    \",{ moduleName: \"customer-site/components/video/video-streaming/video-streaming-players/index.hbs\" })","/* import __COLOCATED_TEMPLATE__ from './index.hbs'; */\nimport { tracked } from '@glimmer/tracking';\nimport {\n ARROW_LEFT_CODE,\n ARROW_RIGHT_CODE,\n ARROW_UP_CODE,\n ARROW_DOWN_CODE,\n addWeakTrapFocusListener,\n removeTrapFocusListener,\n nodeHandlesKeyboardInput\n} from '@adc/ember-utils/utils/a11y';\n// Do not copy this deprecated usage. If you see this, please fix it\n// eslint-disable-next-line ember/no-classic-components\nimport Component from '@ember/component';\nimport { computed, set, action } from '@ember/object';\nimport { alias, equal } from '@ember/object/computed';\nimport { inject as service } from '@ember/service';\nimport { htmlSafe } from '@ember/template';\nimport { restartableTask, timeout } from 'ember-concurrency';\nimport { getCameraItemByGlobalDeviceId } from 'customer-site/components/video/video-streaming/video-streaming-features/camera-items';\nimport { WarningSoundFeatureTour } from 'customer-site/enums/HelpTourType';\nimport { appendStrings, appendStringsIf } from '../../../../utils/strings';\nimport { doOnPlaybackControllers } from '../../video-player/base-video-player';\nimport {\n HybridView,\n HdAspectRatio,\n OnePlusFiveView,\n OnePlusSevenView,\n TwoPlusEightView,\n FourPlusTwoPlusFourView,\n AutoView\n} from '../video-streaming-features/index';\n\nimport type { SafeString } from '@ember/template';\nimport type { TaskGenerator } from 'ember-concurrency';\nimport './_style.scss';\nimport type EnvSettingsService from '@adc/app-infrastructure/services/env-settings';\nimport type LocaleService from '@adc/app-infrastructure/services/locale';\nimport type DomService from '@adc/ember-utils/services/dom';\nimport type BaseStateController from '@adc/video-player/classes/state-controllers/base-state-controller';\nimport type OespPlaybackStateController from '@adc/video-player/classes/state-controllers/oesp-playback-state-controller';\nimport type Camera from 'customer-site/models/video/devices/camera';\nimport type ContextManager from 'customer-site/services/context-manager';\nimport type IdentityManager from 'customer-site/services/identity-manager';\nimport type Stats from 'customer-site/services/stats';\nimport type { AVSDataObject } from '../../advanced-video-search/page/index';\nimport type { AutoViewProperties, CameraItem, Dimensions, LayoutProperties } from '../video-streaming-features/types';\n\nexport type AvsSwitchAbility = {\n canGoToNextClip: boolean;\n canGoToPreviousClip: boolean;\n};\n\ntype CameraGrid = Array>;\n\ntype CameraLocation = {\n row: number;\n column: number;\n};\n\ntype GridDimensions = {\n numRows: number;\n numCols: number;\n};\n\ntype ViewIndexLocationList = {\n row: number[];\n col: number[];\n}[];\n\nconst ExpandedView = 'expanded-view',\n SinglePlayer = 'single-player',\n FullScreen = 'full-screen',\n VerticalPlayerPadding = 2,\n // how long we wait before saving camera reorders, done with drag-drop, to the database. To prevent over-calling the API.\n CameraReorderSaveWaitTimeMs = 10000;\n\n/**\n * List containing all the arrow key code constants.\n */\nconst ArrowKeysList = [ARROW_LEFT_CODE, ARROW_RIGHT_CODE, ARROW_UP_CODE, ARROW_DOWN_CODE];\n\n/**\n * Gets dimensions for the video players.\n */\nfunction getVideoPlayerDimensions(this: VideoStreamingPlayers): Dimensions[] {\n // Size the players based on the size of the .locomote-container divs, with some padding to separate (unless theater mode/full screen).\n return Array.from(document.querySelectorAll('.locomote-container')).map(({ clientHeight }) => {\n const height = clientHeight - (this.isTheaterModeOrFullScreen ? 0 : VerticalPlayerPadding);\n\n return {\n height,\n width: height * HdAspectRatio\n };\n });\n}\n\n/**\n * Sets video player dimensions.\n *\n * @param resetPlayers Whether we should set the player dimensions to zero\n */\nfunction setVideoPlayerDimensions(this: VideoStreamingPlayers, resetPlayers: boolean): void {\n const { cameraItems } = this;\n\n if (!cameraItems) {\n return;\n }\n\n const playerDimensions = getVideoPlayerDimensions.call(this);\n\n // Before each resize we need to minimize the players so they don't stretch the .locomote-container divs that are used in the getVideoPlayerDimensions function.\n // During the resize we just use the getVideoPlayerDimensions function, which looks at the size of the .locomote-container divs to get the appropriate player sizes.\n cameraItems.forEach((cameraItem, idx) =>\n set(cameraItem, 'playerDimensions', resetPlayers ? { height: 0, width: 0 } : playerDimensions[idx])\n );\n}\n\n/**\n * Sets playerDimensionsSet to the desired value.\n *\n * @param value The value playerDimensionsSet should be.\n */\nfunction changePlayerDimensionsSet(this: VideoStreamingPlayers, value: boolean): void {\n // If we are beginning a resize of the players, we need to minimize the players to prevent stretching the .locomote-container divs, which are used to\n // determine the player sizes in getVideoPlayerDimensions.\n if (!value) {\n setVideoPlayerDimensions.call(this, true);\n }\n\n this.playerDimensionsSet = value;\n}\n\n/**\n * Set up the actions following different camera selection key presses.\n */\nfunction setupKeyPressesForCameraSelection(this: VideoStreamingPlayers): void {\n // Start listening for camera swap keyboard presses.\n this.dom.addListener(this, document, 'keydown', (event) => {\n const { target, key, shiftKey } = event as KeyboardEvent,\n numCameras = this.cameraItems?.length;\n\n // Return if there are 0 cameras on the grid and if the camera selector dropdown is open (to prevent up/down arrow key conflicts),\n if (numCameras === 0 || this.camerasSelectorIsOpen) {\n return;\n }\n\n // If the target node already handles keyboard input, ignore.\n // If the event also includes the shiftKey, ignore.\n if ((target && nodeHandlesKeyboardInput(target as Node)) || shiftKey) {\n return;\n }\n\n if (ArrowKeysList.includes(key)) {\n if (!this.cameraItems?.isAny('isSelectedForKeyboardPress')) {\n // Trap focus to the selected player so we will only tab through the elements within that player.\n const selectedPlayerFocusTrapId = addWeakTrapFocusListener(this, {\n scopeSelector: '.general-overlay-features.selected',\n escapeCallback: this.deselectCameraOnGrid,\n treatArrowsAsTabEvents: false,\n oldListenerId: this.selectedPlayerFocusTrapId || ''\n });\n\n this.selectedPlayerFocusTrapId = selectedPlayerFocusTrapId || null;\n }\n\n changeActiveCamera.call(this, key);\n }\n });\n}\n\n/**\n * Gets the number of cameras which are located in the row and column of a specified location in the camera grid\n */\nfunction getNumberCamerasInLocation(\n this: VideoStreamingPlayers,\n row: number,\n col: number\n): { numCamerasInRow: number; numCamerasInCol: number } {\n const { cameraItemsGrid, layoutProperties } = this,\n { layoutType } = layoutProperties || {};\n\n const numRows = cameraItemsGrid.length,\n numCamerasInRow = cameraItemsGrid[row]?.length;\n\n let numCamerasInCol = 0;\n\n if (layoutType === AutoView) {\n numCamerasInCol = cameraItemsGrid[numRows - 1]?.[col] ? numRows : numRows - 1;\n } else {\n for (let i = 0; i < numRows; i++) {\n // If the current value in the grid is null, that means we've reached the end of the column.\n if (cameraItemsGrid[i][col] === null) {\n break;\n }\n\n numCamerasInCol++;\n }\n }\n\n return {\n numCamerasInRow,\n numCamerasInCol\n };\n}\n\n/**\n * Helper function to change the active camera from the current selected camera to the next (based on the key action).\n *\n * @param action The specific key action (arrow left/right/up/down).\n */\nfunction changeActiveCamera(this: VideoStreamingPlayers, action: string): void {\n const { cameraItems, layoutProperties, singlePlayer, cameraItemsGrid, viewIndexLocationList } = this,\n { layoutType } = layoutProperties || {};\n\n if (singlePlayer && cameraItems) {\n set(cameraItems[0], 'isSelectedForKeyboardPress', true);\n return;\n }\n\n if (this.selectedCameraLocation === null) {\n let row, column;\n if (layoutType === AutoView) {\n row = 0;\n column = 0;\n } else if (viewIndexLocationList) {\n const firstViewIndexGridLocations = viewIndexLocationList[0],\n startingRowIndex = firstViewIndexGridLocations.row[0],\n startingColIndex = firstViewIndexGridLocations.col[0];\n\n row = startingRowIndex;\n column = startingColIndex;\n } else {\n // unless theres a bug we should never hit this\n return;\n }\n\n this.selectedCameraLocation = { row, column };\n const numCamerasInLocation = getNumberCamerasInLocation.call(this, row, column);\n\n setNextActiveCamera.call(\n this,\n cameraItemsGrid[row][column] as CameraItem,\n action,\n numCamerasInLocation.numCamerasInCol,\n numCamerasInLocation.numCamerasInRow\n );\n return;\n }\n\n const numCamerasInLocation = getNumberCamerasInLocation.call(\n this,\n this.selectedCameraLocation.row,\n this.selectedCameraLocation.column\n );\n\n setSelectedCameraLocation.call(\n this,\n action,\n numCamerasInLocation.numCamerasInCol,\n numCamerasInLocation.numCamerasInRow\n );\n\n const currentCamera = cameraItems?.findBy('isSelectedForKeyboardPress');\n\n if (currentCamera) {\n set(currentCamera, 'isSelectedForKeyboardPress', false);\n }\n\n setNextActiveCamera.call(\n this,\n currentCamera,\n action,\n numCamerasInLocation.numCamerasInCol,\n numCamerasInLocation.numCamerasInRow\n );\n}\n\n/**\n * Helper function to set isSelectedForKeyboardPress to true for the next active camera.\n *\n * @param currentCamera The current camera that is selected.\n * @param action The left/right/up/down keyboard action.\n * @param numCamerasInCol The number of cameras in the current column.\n * @param numCamerasInRow The number of cameras in the current row.\n */\nfunction setNextActiveCamera(\n this: VideoStreamingPlayers,\n currentCamera?: CameraItem,\n action?: string,\n numCamerasInCol?: number,\n numCamerasInRow?: number\n): void {\n const { cameraItems, layoutProperties, cameraItemsGrid, selectedCameraLocation, viewIndexLocationList } = this,\n { layoutType } = layoutProperties || {};\n\n if (!selectedCameraLocation || !cameraItems) {\n return;\n }\n\n let nextActiveCamera = cameraItemsGrid[selectedCameraLocation.row]?.[selectedCameraLocation.column];\n\n if (layoutType !== AutoView) {\n // If the current camera's view index is the same as the next value in the grid, skip until we find the next camera item in the direction we are navigating.\n if (currentCamera?.viewIndex === nextActiveCamera || nextActiveCamera === null) {\n if (!this.selectedCameraLocation) {\n return;\n }\n\n while (!cameraItems.includes(nextActiveCamera as CameraItem)) {\n setSelectedCameraLocation.call(this, action, numCamerasInCol, numCamerasInRow);\n\n nextActiveCamera =\n cameraItemsGrid[this.selectedCameraLocation.row]?.[this.selectedCameraLocation.column];\n }\n } else {\n // If the current camera is different from the next and we land on values 0 or 1 (i.e. going from small camera to large camera),\n // set the selectedCameraLocation to the location of cameraItems 0 or 1.\n if (viewIndexLocationList && (nextActiveCamera === 0 || nextActiveCamera === 1)) {\n this.selectedCameraLocation = {\n row: viewIndexLocationList[nextActiveCamera].row[0],\n column: viewIndexLocationList[nextActiveCamera].col[0]\n };\n nextActiveCamera = cameraItemsGrid[this.selectedCameraLocation.row][this.selectedCameraLocation.column];\n }\n }\n }\n\n // make sure nextActiveCamera is a cameraItem (isn't a number or null)\n if (nextActiveCamera && typeof nextActiveCamera === 'object') {\n set(nextActiveCamera, 'isSelectedForKeyboardPress', true);\n }\n}\n\n/**\n * Helper function to find and set the next row and column fields for selectedCameraLocation.\n *\n * @param action The left/right/up/down keyboard action.\n * @param numCamerasInCol The number of cameras in the current column.\n * @param numCamerasInRow The number of cameras in the current row.\n */\nfunction setSelectedCameraLocation(\n this: VideoStreamingPlayers,\n action: string,\n numCamerasInCol: number,\n numCamerasInRow: number\n): void {\n const { isRtl, selectedCameraLocation } = this;\n\n if (!selectedCameraLocation) {\n return;\n }\n\n let directionalValueCol = 0,\n directionalValueRow = 0;\n\n if (action === ARROW_LEFT_CODE || action === ARROW_RIGHT_CODE) {\n directionalValueCol = action === ARROW_LEFT_CODE ? -1 : 1;\n // Negate if the customer account is in a RTL language setting.\n if (isRtl) {\n directionalValueCol *= -1;\n }\n } else {\n directionalValueRow = action === ARROW_UP_CODE ? -1 : 1;\n }\n\n const nextRow = (numCamerasInCol + selectedCameraLocation.row + directionalValueRow) % numCamerasInCol,\n nextColumn = (numCamerasInRow + selectedCameraLocation.column + directionalValueCol) % numCamerasInRow;\n\n this.selectedCameraLocation = { row: nextRow, column: nextColumn };\n}\n\n/**\n * Returns a grid to be populated using the ordered view index locations.\n *\n * Examples:\n * Box drawing representations of the initial grid and how view index\n * locations are placed in the grid along with placeholders (ints represented by \"0\" and \"1\")\n *\n * HybridView (isHybridWide)\n * ┌───┬─┐ ┌───┬─┐\n * │ N │N│ │ 0 │1│\n * │ ├─┤ │ ├─┤\n * │\"0\"│N│ -> │\"0\"│2│\n * │ ├─┤ │ ├─┤\n * │\"0\"│N│ │\"0\"│3│\n * └───┴─┘ └───┴─┘\n *\n * FourPlusTwoPlusFourView\n * ┌─┬───┬─┐ ┌─┬───┬─┐\n * │N│ N │N│ │2│ 0 │3│\n * ├─┤ ├─┤ ├─┤ ├─┤\n * │N│\"0\"│N│ │4│\"0\"│5│\n * ├─┼───┼─┤ -> ├─┼───┼─┤\n * │N│ N │N│ │6│ 1 │7│\n * ├─┤ ├─┤ ├─┤ ├─┤\n * │N│\"1\"│N│ │8│\"1\"│9│\n * └─┴───┴─┘ └─┴───┴─┘\n */\nfunction getUnfilledHybridGrid(this: VideoStreamingPlayers): CameraGrid {\n const { viewIndexLocationList, hybridGridDimensions } = this;\n const unfilledCameraGrid: CameraGrid = [];\n\n if (!hybridGridDimensions || !viewIndexLocationList) {\n return unfilledCameraGrid;\n }\n\n // First, populate the array with null values.\n for (let i = 0; i < hybridGridDimensions.numRows; i++) {\n unfilledCameraGrid.push([]);\n for (let j = 0; j < hybridGridDimensions.numCols; j++) {\n unfilledCameraGrid[i].push(null);\n }\n }\n\n // Now, populate the remaining spots for the large cameras with placeholder values (ints represented by \"0\" and \"1\").\n // We check just the first 2 indexes because view indexes that have placeholders are placed at the start of the list and\n // layouts will have at most two placeholder indexes.\n for (let i = 0; i < 2; i++) {\n // The starting index 0 is used for the camera position. Indexes 1 and up are used for placeholders.\n for (let j = 1; j < viewIndexLocationList[i].row.length; j++) {\n const row = viewIndexLocationList[i].row[j],\n col = viewIndexLocationList[i].col[j];\n unfilledCameraGrid[row][col] = i;\n }\n }\n\n return unfilledCameraGrid;\n}\n\n/**\n * Sets the viewIndexLocationList and hybridGridDimensions properties.\n */\nfunction setViewIndexLocationsAndGridDimensions(this: VideoStreamingPlayers): void {\n const { layoutProperties } = this,\n { layoutType, isHybridWide } = layoutProperties || {};\n\n switch (layoutType) {\n case HybridView:\n this.viewIndexLocationList = isHybridWide\n ? [\n { row: [0, 1, 2], col: [0, 0, 0] },\n { row: [0], col: [1] },\n { row: [1], col: [1] },\n { row: [2], col: [1] }\n ]\n : [\n { row: [0, 0, 0], col: [0, 1, 2] },\n { row: [1], col: [0] },\n { row: [1], col: [1] },\n { row: [1], col: [2] }\n ];\n this.hybridGridDimensions = isHybridWide ? { numRows: 3, numCols: 2 } : { numRows: 2, numCols: 3 };\n break;\n case OnePlusFiveView:\n this.viewIndexLocationList = [\n { row: [0, 0, 1, 1], col: [0, 1, 0, 1] },\n { row: [0], col: [2] },\n { row: [1], col: [2] },\n { row: [2], col: [0] },\n { row: [2], col: [1] },\n { row: [2], col: [2] }\n ];\n this.hybridGridDimensions = { numRows: 3, numCols: 3 };\n break;\n case OnePlusSevenView:\n this.viewIndexLocationList = [\n { row: [0, 0, 0, 1, 1, 1, 2, 2, 2], col: [0, 1, 2, 0, 1, 2, 0, 1, 2] },\n { row: [0], col: [3] },\n { row: [1], col: [3] },\n { row: [2], col: [3] },\n { row: [3], col: [0] },\n { row: [3], col: [1] },\n { row: [3], col: [2] },\n { row: [3], col: [3] }\n ];\n this.hybridGridDimensions = { numRows: 4, numCols: 4 };\n break;\n case TwoPlusEightView:\n this.viewIndexLocationList = [\n { row: [0, 1], col: [0, 0] },\n { row: [2, 3], col: [0, 0] },\n { row: [0], col: [1] },\n { row: [0], col: [2] },\n { row: [1], col: [1] },\n { row: [1], col: [2] },\n { row: [2], col: [1] },\n { row: [2], col: [2] },\n { row: [3], col: [1] },\n { row: [3], col: [2] }\n ];\n this.hybridGridDimensions = { numRows: 4, numCols: 3 };\n break;\n case FourPlusTwoPlusFourView:\n this.viewIndexLocationList = [\n { row: [0, 1], col: [1, 1] },\n { row: [2, 3], col: [1, 1] },\n { row: [0], col: [0] },\n { row: [0], col: [2] },\n { row: [1], col: [0] },\n { row: [1], col: [2] },\n { row: [2], col: [0] },\n { row: [2], col: [2] },\n { row: [3], col: [0] },\n { row: [3], col: [2] }\n ];\n this.hybridGridDimensions = { numRows: 4, numCols: 3 };\n break;\n }\n}\n\n/**\n * @classdesc\n *\n * Component that manages the sizes and layout of video players.\n */\nexport default class VideoStreamingPlayers extends Component {\n tagName = '';\n\n @service declare locale: LocaleService;\n @service declare contextManager: ContextManager;\n @service declare dom: DomService;\n @service declare stats: Stats;\n @service declare envSettings: EnvSettingsService;\n @service declare identityManager: IdentityManager;\n\n // region Component Overrides\n\n /** @override */\n // Do not copy this deprecated usage. If you see this, please fix it\n // eslint-disable-next-line ember/classic-decorator-hooks\n init() {\n super.init();\n this.updateCommands && this.updateCommands(null, doOnPlaybackControllers.bind(this));\n\n // Camera selection keyboard shortcuts restricted under internal beta for now.\n if (this.hasInternalBetaAccess) {\n setupKeyPressesForCameraSelection.call(this);\n }\n }\n\n /** @override */\n // Do not copy this deprecated usage. If you see this, please fix it\n // eslint-disable-next-line ember/no-component-lifecycle-hooks\n didRender() {\n super.didRender();\n\n // Set player dimensions if we have the flag on, and the locomote containers are ready.\n if (!this.playerDimensionsSet && document.querySelector('.locomote-container')) {\n // Update video player dimensions and turn off flag.\n setVideoPlayerDimensions.call(this, false);\n changePlayerDimensionsSet.call(this, true);\n }\n }\n\n /** @override */\n willDestroy() {\n // normally this task will wait 10 seconds, but if we're destroying before the 10 second timer reaches, lets save immediately\n if ((this.saveCamerasOrderTask as any).isRunning) {\n this.saveCameraGroupOrderFromCamItemsOrder?.();\n }\n\n super.willDestroy();\n }\n\n // endregion\n\n /**\n * Whether we are in RTL.\n */\n @alias('locale.isRtl')\n declare isRtl: boolean;\n\n /**\n * Does this customer currently have internal beta access? (Currently used for 2-way audio keyboard shortcuts).\n */\n @alias('contextManager.identityModel.hasInternalBetaAccess')\n declare hasInternalBetaAccess: boolean;\n\n /**\n * Is this an Operator Site session?\n */\n declare isOperatorSite: boolean;\n\n /**\n * If this component is rendered on an operator page and only one camera is selected or available, we should show the OperatorTitle component\n */\n @computed('cameraItems.length', 'isOperatorSite', 'isLiveView')\n get showOperatorTitle(): boolean {\n return !this.isLiveView && this.isOperatorSite && this.cameraItems?.length === 1;\n }\n\n /**\n * In-line CSS for the container's dimensions. Height and width are passed in from the parent component.\n */\n @computed(\n 'dimensions.{height,width}',\n 'singlePlayerDimensions.{height,width}',\n 'singlePlayer',\n 'bestAutoView',\n 'layoutProperties.{cameraExpanded,layoutType}'\n )\n get containerStyle(): SafeString {\n const { bestAutoView, layoutProperties, singlePlayer, singlePlayerDimensions } = this,\n { cameraExpanded, layoutType } = layoutProperties || {};\n\n const dimensions = singlePlayer || cameraExpanded ? singlePlayerDimensions : this.dimensions;\n\n if (!dimensions) {\n return htmlSafe('');\n }\n\n let style = `height:${dimensions.height}px;width:${dimensions.width}px;`;\n\n if (layoutType === AutoView && bestAutoView) {\n const widthPercent = 100 / bestAutoView.columns,\n heightPercent = 100 / bestAutoView.rows;\n\n style += ` --playerWidth: ${widthPercent}%; --playerHeight: ${heightPercent}%;`;\n }\n\n return htmlSafe(style);\n }\n\n /**\n * Class for the container. Used in the CSS to layout the .locomote-container divs.\n */\n @computed('layoutProperties.{cameraExpanded,isFullScreen,isHybridWide,layoutType}', 'singlePlayer')\n get containerClass(): string {\n const { layoutProperties, singlePlayer } = this,\n { cameraExpanded, layoutType, isFullScreen, isHybridWide } = layoutProperties || {};\n\n let containerClass = appendStringsIf(!!isFullScreen, '', FullScreen);\n\n if (!layoutType) {\n return containerClass;\n }\n\n if (cameraExpanded) {\n return appendStrings(containerClass, ExpandedView);\n }\n\n if (singlePlayer) {\n return appendStrings(containerClass, SinglePlayer);\n }\n\n if (\n [AutoView, OnePlusFiveView, OnePlusSevenView, TwoPlusEightView, FourPlusTwoPlusFourView].includes(\n layoutType\n )\n ) {\n return appendStrings(containerClass, layoutType);\n }\n\n containerClass = appendStrings(containerClass, HybridView);\n\n return appendStringsIf(!!isHybridWide, containerClass, 'wide');\n }\n\n /**\n * Whether we are in live view mode (as opposed to playback or some other mode).\n */\n isLiveView = false;\n\n /**\n * A collection of simple properties related to the current layout. (Check the video-streaming-features component for the list of properties)\n */\n layoutProperties: LayoutProperties | null = null;\n\n /**\n * The row/column location of the selected camera in the grid.\n */\n selectedCameraLocation: CameraLocation | null = null;\n\n /**\n * The listener to trap focus to the selected camera.\n */\n selectedPlayerFocusTrapId: string | null = null;\n\n /**\n * If the page is currently in theater mode or full screen.\n */\n isTheaterModeOrFullScreen = false;\n\n /**\n * A set of which SVRs are currently in the process of establishing a microphone connection.\n * We track this to prevent the same SVR from making multiple simultaneous microphone connection attempts.\n *\n * @type {Set}\n */\n @tracked svrIdsWithMicrophoneConnectionInProgress = new Set();\n\n /**\n * An array with the location(s) of each camera on the grid (in order of viewIndex), based on the current layout type.\n */\n @tracked viewIndexLocationList: ViewIndexLocationList | null = null;\n\n /**\n * The dimensions of the hybrid camera grid array.\n */\n @tracked hybridGridDimensions: GridDimensions | null = null;\n\n /**\n * The viewIndex of the player currently being dragged over (when dragging and dropping to swap player locations). Null if none\n */\n @tracked draggingOverIndex: number | null = null;\n\n /**\n * The viewIndex of the player that a drag-drop was started from. Null if none\n */\n @tracked draggingOriginIndex: number | null = null;\n\n /**\n * The global device id of the player that a drag-drop was started from. null if none\n */\n @tracked draggingOriginGlobalDeviceId: string | null = null;\n\n /**\n * The global device id of the oesp player master pane's camera that is currently selected on the live view.\n * Used for LIVE VIEW ONLY.\n */\n @tracked selectedOespMasterPaneCameraId: string | null = null;\n\n /**\n * Applicable only to OE Live-View players. When true, the idle audio icon will be hidden.\n */\n @tracked forceHideIdleAudioIcon = false;\n\n /**\n * Only applicable to Live-View OESP streams.\n * When the SVR streams reload to connect the users microphone, this value will update with the SVR's ID/mac.\n * When this value updates, it triggers the connectMicrophoneForAllCamerasOnSvr function on the live-view-players, causing all microphones for the SVR to be connected.\n */\n @tracked svrIdRefreshedFromMicrophoneConnection: string | null = null;\n\n /**\n * If the user is currently dragging over the same player that they started the drag-drop from, if any\n */\n @computed('draggingOriginIndex', 'draggingOverIndex')\n get isDraggingOverOrigin(): boolean {\n return this.draggingOverIndex !== null && this.draggingOriginIndex === this.draggingOverIndex;\n }\n\n /**\n * Flag to indicate whether we should resize the players. Used in the didRender hook.\n */\n playerDimensionsSet = false;\n\n /**\n * Whether there is only one player.\n */\n @equal('cameraItems.length', 1)\n declare singlePlayer: boolean;\n\n /**\n * The camera items we receive from the top-level component.\n */\n cameraItems: CameraItem[] | null = null;\n\n /**\n * The playback state controllers for each player.\n */\n playbackStateControllers?: BaseStateController[];\n\n /**\n * Whether we show the players. Passed in from top-level component.\n */\n showCameraItems = false;\n\n /**\n * If there 2 or more cameras that are in a timed out state. This variable only exists on the live video players as the timeout behavior functions differently\n * on playback players(sd/svr)\n */\n moreThanOneCameraTimedOut = false;\n\n /**\n * The dimensions for the players container. Passed in from top-level component.\n */\n dimensions: Dimensions | null = null;\n\n /**\n * The dimensions for when we only have one player. Passed in from top-level component.\n */\n singlePlayerDimensions: Dimensions | null = null;\n\n /**\n * A ForcedStreamingMethodEnum for if streaming is being forced to a certain type via query param.\n */\n forcedStreamingMethodFromQueryParam?: number;\n\n /**\n * Whether we are in enterprise context, i.e. whether we should show the system group subtext on the camera name labels.\n */\n isEnterprise = false;\n\n /**\n * Whether we should use HD streams for this user's cameras.\n */\n useHdStream = false;\n\n /**\n * Has the Warning Sound help tour been shown on any camera?\n */\n hasShownWarningSoundHelpTour = false;\n\n /**\n * Should we enable the Advanced Video Search link?\n */\n enableAdvancedVideoSearch = false;\n\n /**\n * Passed in arg for whether the player type (SD/SVR) supports downloading thumbnails.\n */\n playerTypeSupportsThumbnailsDownload = false;\n\n /**\n * Passed in arg for the property on the camera model that is used for determining whether the camera supports downloading playback thumbnails.\n */\n supportsDownloadingThumbnailsProperty: string | null = null;\n\n /**\n * If the cameras selector dropdown is open.\n */\n camerasSelectorIsOpen = false;\n\n /**\n * The Advanced Video Search Data Object\n */\n avsDataObject?: AVSDataObject;\n\n /**\n * If the user can use drag and drop to re-arrange the players\n */\n @computed('layoutProperties.cameraExpanded', 'singlePlayer')\n get enableDragAndDrop(): boolean {\n return !this.layoutProperties?.cameraExpanded && !this.singlePlayer;\n }\n\n /**\n * The best (minimizes whitespace) view for showing the selected players (while in auto view) in terms of how many rows of players to use,\n * how many columns, and the sizing of them all.\n */\n bestAutoView?: AutoViewProperties;\n\n /**\n * An array of methods for retrying timed out players. These should come from the player components themselves. Used only for live video players.\n * (playback handles timeouts slightly differently)\n */\n retryTimedOutMethods: (() => void)[] = [];\n\n /**\n * Download a clip for the selected device\n */\n downloadClip?: (deviceId: string, cameraIndex: number) => void;\n\n /**\n * Download thumbnails for the selected device\n */\n downloadThumbnails?: (deviceId: string, cameraIndex: number) => void;\n\n /**\n * An action to expand the camera at this index\n */\n expandCameraIndex?: (index: number) => void;\n\n /**\n * Action when the user does a swap with cameras\n */\n onSwapCamera?: () => void;\n\n /**\n * Action when play ends for a device\n */\n playEnded?: (cameraIndex: number, isTimeout: boolean, isEndOfStream: boolean) => void;\n\n /**\n * An action to reset the expanded camera index\n */\n resetExpandedCameraIndex?: () => void;\n\n /**\n * Saves the camera group order based on the current camera items order\n */\n saveCameraGroupOrderFromCamItemsOrder?: () => void;\n\n /**\n * An action when the user changes which camera is now the large camera (in hybrid mode)\n */\n setLargeHybridCamera?: (deviceId: string) => void;\n\n /**\n * Action for setting the loading percentage for a specific device\n */\n setLoadingPercentage?: (loadingPercentage: number, cameraIndex: number) => void;\n\n /**\n * Action for synchronizing the time between the client and the video player.\n */\n syncTimer?: (newOffset: number, cameraIndex: number) => void;\n\n /**\n * Storing the playback state controller commands.\n */\n updateCommands?: (command: string | null, callback: (commandName: string, value: string) => boolean) => void;\n\n /**\n * Action for setting the page/player state\n */\n updatePageAndPlayerState?: (newState: number, cameraIndex: number) => void;\n\n /**\n * A 2D array representing the camera grid matching the way it is currently being displayed.\n * For example, if there are 3 rows and 2 columns, this array will represent the camera items in those rows/columns.\n */\n @computed(\n 'bestAutoView.columns',\n 'cameraItems.@each.viewIndex',\n 'layoutProperties.{isHybridWide,layoutType}',\n 'viewIndexLocationList'\n )\n get cameraItemsGrid(): CameraGrid {\n const { cameraItems, layoutProperties } = this;\n\n if (!cameraItems) {\n return [];\n }\n\n const { layoutType } = layoutProperties || {},\n cameraItemsSortedByViewIndex = cameraItems.sortBy('viewIndex'),\n numCameras = cameraItems.length || 0;\n\n let cameraGrid: CameraGrid = [];\n\n if (layoutType === AutoView) {\n const { bestAutoView } = this,\n numCamerasInRow = bestAutoView?.columns || 0;\n\n let currentRowArray = [],\n currentViewIndex = 0,\n currentIndexInRow = 0;\n\n while (currentViewIndex < numCameras) {\n while (currentIndexInRow < numCamerasInRow && currentViewIndex < numCameras) {\n currentRowArray.push(cameraItemsSortedByViewIndex[currentViewIndex]);\n currentViewIndex++;\n currentIndexInRow++;\n }\n\n cameraGrid.push(currentRowArray);\n currentRowArray = [];\n currentIndexInRow = 0;\n }\n } else {\n setViewIndexLocationsAndGridDimensions.call(this);\n\n const { viewIndexLocationList } = this;\n\n if (!viewIndexLocationList) {\n return cameraGrid;\n }\n cameraGrid = getUnfilledHybridGrid.call(this);\n\n // Populate the camera grid with camera items.\n for (let viewIndex = 0; viewIndex < numCameras; viewIndex++) {\n const location = viewIndexLocationList[viewIndex];\n cameraGrid[location.row[0]][location.col[0]] = cameraItemsSortedByViewIndex[viewIndex];\n }\n }\n\n return cameraGrid;\n }\n\n /**\n * Has the Warning Sound help tour been shown on any camera?\n */\n @computed('hasShownWarningSoundHelpTour', 'contextManager.identityModel.helpTours.[]')\n get shouldShowWarningSoundHelpTour(): boolean {\n return (\n !this.hasShownWarningSoundHelpTour &&\n this.contextManager.identityModel.helpTours.includes(WarningSoundFeatureTour)\n );\n }\n\n /**\n * If we can switch between selected videos (this is used with AVS going through results)\n */\n @computed('avsDataObject.{searchResults,selectedResultIndex}')\n get avsResultSwitchAbility(): AvsSwitchAbility | null {\n const { avsDataObject } = this;\n\n if (!avsDataObject) {\n return null;\n }\n\n const { searchResults, selectedResultIndex } = avsDataObject;\n\n if (!searchResults) {\n return null;\n }\n\n return {\n canGoToNextClip: selectedResultIndex != null && selectedResultIndex < searchResults.length,\n canGoToPreviousClip: selectedResultIndex != null && selectedResultIndex > 0\n };\n }\n\n /**\n * Does the camera and player type support downloading playback thumbnails?\n */\n supportsThumbnailsDownload(\n playerTypeSupportsDownloadingThumbnails: boolean,\n supportsDownloadingThumbnailsProperty: string | null,\n camera: Camera\n ): boolean {\n return (\n playerTypeSupportsDownloadingThumbnails &&\n !!supportsDownloadingThumbnailsProperty &&\n (camera.get(supportsDownloadingThumbnailsProperty) as boolean)\n );\n }\n\n /**\n * Does the camera support thumbnail search?\n */\n supportsThumbnailSearch(camera: Camera): boolean {\n return camera.supportsThumbnailSearch;\n }\n\n /**\n * Observer of camera items to kill any currently running saveCamerasOrderTask instances\n */\n @action\n cameraItemsObserver(): void {\n // Cancel the saveCamerasOrderTask (which saves the cameraItems re-arranges to the databases) because the cameraItems no longer matches what it was before\n // todo VID-52483\n (this.saveCamerasOrderTask as any).cancelAll();\n this.deselectCameraOnGrid();\n }\n\n /**\n * Observer to call changePlayerDimensionsSet once players container dimensions update.\n */\n @action\n dimensionsChangeObserver(): void {\n changePlayerDimensionsSet.call(this, false);\n }\n\n /**\n * Expands the view to one camera on the page.\n *\n * @param index The camera to expand.\n */\n @action\n expandCamera(index: number): void {\n changePlayerDimensionsSet.call(this, false);\n this.expandCameraIndex && this.expandCameraIndex(index);\n }\n\n /**\n * Returns to the grid or hybrid view for the page.\n */\n @action\n returnToGroup(): void {\n changePlayerDimensionsSet.call(this, false);\n this.resetExpandedCameraIndex && this.resetExpandedCameraIndex();\n }\n\n /**\n * Swaps the specified camera into a newly specified viewIndex (viewIndex is the index of where the video is located on the page, starting with 0)\n *\n * @param cameraToSwap The camera item to swap into the large position.\n * @param newViewIndex\n */\n @action\n swapCamera(cameraToSwap: CameraItem, newViewIndex: number) {\n const { cameraItems } = this;\n const originalViewIndex = cameraToSwap.viewIndex;\n\n if (originalViewIndex === newViewIndex) {\n return;\n }\n\n const cameraIsMovingDown = originalViewIndex > newViewIndex;\n\n const camerasToShift = cameraIsMovingDown\n ? cameraItems?.filter(\n (cameraItem) => cameraItem.viewIndex < originalViewIndex && cameraItem.viewIndex >= newViewIndex\n )\n : cameraItems?.filter(\n (cameraItem) => cameraItem.viewIndex <= newViewIndex && cameraItem.viewIndex > originalViewIndex\n );\n\n set(cameraToSwap, 'viewIndex', newViewIndex);\n\n // Everything that was previously displayed above/below the cameraToSwap needs to move down one place\n camerasToShift?.forEach((cameraItem) => {\n const newViewIndex = cameraItem.viewIndex + (cameraIsMovingDown ? 1 : -1);\n set(cameraItem, 'viewIndex', newViewIndex);\n });\n\n changePlayerDimensionsSet.call(this, false);\n\n if (cameraToSwap.model) {\n this.setLargeHybridCamera && this.setLargeHybridCamera(cameraToSwap.model.globalDeviceId || '');\n }\n\n this.onSwapCamera?.();\n (this.saveCamerasOrderTask as any).perform();\n this.deselectCameraOnGrid();\n }\n\n /**\n * Deselect the current selected camera if the user clicks outside the players container.\n */\n @action\n deselectCameraOnGrid(): void {\n const currentCamera = this.cameraItems?.findBy('isSelectedForKeyboardPress');\n\n if (currentCamera) {\n set(currentCamera, 'isSelectedForKeyboardPress', false);\n }\n\n removeTrapFocusListener(this.selectedPlayerFocusTrapId || '');\n this.selectedPlayerFocusTrapId = null;\n this.selectedCameraLocation = null;\n }\n\n /**\n * Opens the download thumbnail modal.\n */\n @action\n openDownloadThumbnailsModal(cameraIndex: number, deviceId: string): void {\n this['downloadThumbnails']?.(deviceId, cameraIndex);\n }\n\n /**\n * Opens the download clip modal.\n */\n @action\n openDownloadClipModal(cameraIndex: number, deviceId: string): void {\n this['downloadClip']?.(deviceId, cameraIndex);\n }\n\n /**\n * Action for when a players streaming has ended.\n *\n * @note This is only used for playback players.\n * @param isTimeout Whether the playback ending is triggered by a timeout.\n * @param isEndOfStream if we've reached the end of the stream.\n */\n @action\n onPlayEnded(cameraIndex: number, _globalDeviceId: string, isTimeout: boolean, isEndOfStream: boolean): void {\n // This is defined as follows in the template: playEnded=(action 'onPlayEnded' cameraItem.model.id)\n // We need to discard the globalDeviceId here.\n this['playEnded']?.(cameraIndex, isTimeout, isEndOfStream);\n }\n\n /**\n * Sets the loading percentage for the camera selected.\n */\n @action\n onSetLoadingPercentage(cameraIndex: number, loadingPercentage: number): void {\n this['setLoadingPercentage']?.(loadingPercentage, cameraIndex);\n }\n\n /**\n * Changes the state of the camera selected.\n */\n @action\n onUpdatePageAndPlayerState(cameraIndex: number, newState: number): void {\n this['updatePageAndPlayerState']?.(newState, cameraIndex);\n }\n\n /**\n * Periodically synchronizes the time between the client and the video player.\n */\n @action\n onSyncTimer(cameraIndex: number, newOffset: number): void {\n this['syncTimer']?.(newOffset, cameraIndex);\n }\n\n /**\n * Callback to start live view relay once all openeye players on the controller are attached.\n */\n @action\n onAttachToOespController(camera: Camera, playbackStateController: OespPlaybackStateController): void {\n camera.playbackStateController = playbackStateController;\n\n const playersAttachedToController = playbackStateController.players.filter((player) => {\n return player.component?.playbackStateControllerInitCompleted;\n });\n\n const playersUsingController = this.cameraItems?.filter((cameraItem) => {\n return cameraItem.model?.playbackStateController === playbackStateController;\n });\n\n if (playersAttachedToController.length === playersUsingController?.length) {\n playbackStateController.setupPlayers(null, 1, this.useHdStream);\n playbackStateController.startOespLiveRelay();\n }\n }\n\n /**\n * When the selected OESP master pane is switched, this function will get called from the live-view-player component.\n * This will set the selectedOespMasterPaneCameraId to the new cameraId.\n * Used only for the Live View.\n */\n @action\n setSelectedOespMasterPaneCameraId(cameraId: string): void {\n // Making sure the tracked property has actually changed, otherwise the tracked property will update, setting off the did-update modifier in live-view-player\n if (this.selectedOespMasterPaneCameraId !== cameraId) {\n this.selectedOespMasterPaneCameraId = cameraId;\n }\n }\n\n /**\n * Set the hideIdleAudioIcon value to the boolean passed in.\n */\n @action setForceHideIdleAudioIcon(value: boolean): void {\n this.forceHideIdleAudioIcon = value;\n }\n\n /**\n * After using a half-duplex microphone, this function will get hit from the two-way-audio-buttons component.\n * This will quickly change the selectedOespMasterPaneCameraId so that all the OESP streams will temporarily disable the 2WA buttons.\n * Used only for the Live View.\n */\n @action\n enableCameraAudioAfterPauseStarted(): void {\n // Quickly change the selectedOespMasterPaneCameraId to null, then its original value so that the did-update modifier in live-view-player gets triggered.\n const cameraId = this.selectedOespMasterPaneCameraId;\n this.selectedOespMasterPaneCameraId = null;\n this.selectedOespMasterPaneCameraId = cameraId;\n }\n\n /**\n * Action called by the video player components which send up a method for resuming timed out videos. We're adding those methods to an array for use later\n */\n @action\n attachResumeMethod(index: number, method: () => void): void {\n this.retryTimedOutMethods[index] = method;\n }\n\n /**\n * Call the resume methods from the live video components, which should resume all timed out cameras\n */\n @action\n retryAllTimedOutCameras(): void {\n const { cameraItems } = this;\n\n if (!cameraItems) {\n return;\n }\n\n for (let i = 0; i < cameraItems.length; i++) {\n this.retryTimedOutMethods[i]();\n }\n }\n\n /**\n * When starting to drag a player, lets save the view index and set the drag image (for swapping player view indexes)\n */\n @action\n onDragStart(viewIndex: number, event: DragEvent): void {\n if (!this.enableDragAndDrop) {\n return;\n }\n\n const cameraToSwap = this.cameraItems?.find((cameraItem) => cameraItem.viewIndex === viewIndex);\n\n if (!cameraToSwap || !cameraToSwap.model) {\n return;\n }\n\n this.draggingOriginGlobalDeviceId = cameraToSwap.model.id;\n this.draggingOriginIndex = viewIndex;\n\n const videoElement = document.querySelector(\n '.locomote-container.index-' + viewIndex + ' .video-container'\n ) as HTMLElement;\n\n if (!videoElement) {\n return;\n }\n\n const { offsetWidth, offsetHeight } = videoElement;\n\n // Setting the drag image to look like the video element, and offset values so that the mouse is in the middle of the drag image\n event.dataTransfer?.setDragImage(videoElement, offsetWidth / 2, offsetHeight / 2);\n }\n\n /**\n * When dragging a player over another player, update the draggingOverIndex (which highlights the player its over)\n */\n @action\n onDragOver(viewIndex: number, event: DragEvent): void {\n if (!this.enableDragAndDrop) {\n return;\n }\n\n // Prevent default needed to allow the hover action\n event.preventDefault();\n\n if (viewIndex === this.draggingOverIndex) {\n return;\n }\n\n this.draggingOverIndex = viewIndex;\n\n const { cameraItems, draggingOriginGlobalDeviceId } = this;\n\n if (!cameraItems || !draggingOriginGlobalDeviceId) {\n return;\n }\n\n const cameraToSwap = getCameraItemByGlobalDeviceId(draggingOriginGlobalDeviceId, cameraItems);\n\n if (!cameraToSwap) {\n return;\n }\n\n this.swapCamera(cameraToSwap, viewIndex);\n }\n\n /**\n * When dropping a player onto another player, swap the player view indexes\n */\n @action\n onDrop(): void {\n if (!this.enableDragAndDrop) {\n return;\n }\n\n this.draggingOverIndex = null;\n }\n\n /**\n * When leaving a drag area, set the dragging over index to null.\n */\n @action\n onDragLeave(): void {\n this.draggingOverIndex = null;\n }\n\n /**\n * Updates whether or not the given SVR currently has a microphone connection attempt in progress.\n */\n @action\n setMicrophoneConnectionInProgressForSvr(svrId: string, inProgress: boolean) {\n if (svrId) {\n if (inProgress) {\n this.svrIdsWithMicrophoneConnectionInProgress.add(svrId);\n } else {\n this.svrIdsWithMicrophoneConnectionInProgress.delete(svrId);\n }\n }\n }\n\n /**\n * Calls the method to save the camera group order to match the order of the camera Items (based on their viewIndex).\n * Set to be a restartableTask with a 10 second timeout so that the method only triggers once if a user does several of these quickly in a row\n */\n @restartableTask()\n *saveCamerasOrderTask(): TaskGenerator {\n // dont wait if this is an integration test, since we dont want to slow down tests\n if (!this.envSettings.isTestEnvironment()) {\n yield timeout(CameraReorderSaveWaitTimeMs);\n }\n\n this.saveCameraGroupOrderFromCamItemsOrder?.();\n }\n}\n","import { precompileTemplate } from \"@ember/template-compilation\";\nexport default precompileTemplate(\"
    \\n
    {{@caption}}
    \\n
    \\n {{#each this.shortcutDescriptions as |shortcut|}}\\n
    \\n
    \\n {{#each shortcut.keyDescriptions as |key|}}\\n
    {{key.text}}
    \\n {{/each}}\\n
    \\n
    {{shortcut.description}}
    \\n
    \\n {{/each}}\\n
    \\n
    \",{ moduleName: \"customer-site/components/video/video-streaming/video-streaming-toolbar/shortcut-table/index.hbs\" })","/* import __COLOCATED_TEMPLATE__ from './index.hbs'; */\nimport Component from '@glimmer/component';\nimport {\n B_KEY,\n C_KEY,\n D_KEY,\n E_KEY,\n F_KEY,\n N_KEY,\n S_KEY,\n T_KEY,\n SPACE_KEY,\n LEFT_ARROW_KEY,\n RIGHT_ARROW_KEY,\n UP_ARROW_KEY,\n DOWN_ARROW_KEY,\n EQUALS_KEY,\n LEFT_BRACKET_KEY,\n RIGHT_BRACKET_KEY,\n ESCAPE_KEY,\n TAB_KEY,\n ENTER_KEY,\n SHIFT_KEY\n} from '@adc/ember-utils/utils/a11y';\nimport { computed } from '@ember/object';\n\nimport './_style.scss';\n\nexport const MouseScroll = -1;\n\nexport const V_KEY = 86,\n H_KEY = 72,\n G_KEY = 71,\n A_KEY = 65; // Refactor these keyCodes to use key values in VID-52378.\n\n/**\n * @classdesc\n * Representation of a single key on a keyboard.\n */\nclass KeyDescription {\n isLarge: boolean;\n text: string;\n\n constructor(text: string, isLarge: boolean) {\n this.text = text;\n this.isLarge = isLarge;\n }\n}\n\n/**\n * @classdesc\n * Representation of a keyboard shortcut, where a keyboard shortcut is defined as\n * one or more keys pressed in unison with a description of the observed behavior.\n */\nclass ShortcutDescription {\n description: string;\n keyDescriptions: KeyDescription[];\n\n constructor(description: string, keyDescriptions: KeyDescription[]) {\n this.description = description;\n this.keyDescriptions = keyDescriptions;\n }\n}\n\n/**\n * Map from KeyboardEvent.keyCodes to our internal representation describing the key to be rendered.\n * See: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode for more details on keyCodes.\n */\nconst keyMap: Map = new Map([\n [A_KEY, new KeyDescription('A', false)],\n [B_KEY, new KeyDescription('B', false)],\n [C_KEY, new KeyDescription('C', false)],\n [D_KEY, new KeyDescription('D', false)],\n [E_KEY, new KeyDescription('E', false)],\n [F_KEY, new KeyDescription('F', false)],\n [G_KEY, new KeyDescription('G', false)],\n [H_KEY, new KeyDescription('H', false)],\n [N_KEY, new KeyDescription('N', false)],\n [S_KEY, new KeyDescription('S', false)],\n [V_KEY, new KeyDescription('V', false)],\n [T_KEY, new KeyDescription('T', false)],\n [UP_ARROW_KEY, new KeyDescription('↑', false)],\n [DOWN_ARROW_KEY, new KeyDescription('↓', false)],\n [LEFT_ARROW_KEY, new KeyDescription('←', false)],\n [RIGHT_ARROW_KEY, new KeyDescription('→', false)],\n [LEFT_BRACKET_KEY, new KeyDescription('[', false)],\n [RIGHT_BRACKET_KEY, new KeyDescription(']', false)],\n [ENTER_KEY, new KeyDescription('↵', false)],\n [EQUALS_KEY, new KeyDescription('=', false)],\n [ESCAPE_KEY, new KeyDescription('Esc', false)],\n [SHIFT_KEY, new KeyDescription('Shift', true)],\n [SPACE_KEY, new KeyDescription('Space', true)],\n [TAB_KEY, new KeyDescription('Tab', false)],\n [MouseScroll, new KeyDescription('Scroll', true)]\n]);\n\ninterface ShortcutTableSignature {\n Element: HTMLDivElement;\n Args: {\n caption: string;\n shortcuts: { keys: number[]; description: string }[];\n };\n}\n\n/**\n * @classdesc\n * Component representing a visual table of one or more shortcuts to be displayed for the user.\n */\nexport default class ShortcutTable extends Component {\n /**\n * The array of shortcuts to be rendered out in the shortcut-table.\n */\n @computed('args.shortcuts')\n get shortcutDescriptions(): ShortcutDescription[] {\n return this.args.shortcuts.map((shortcut) => {\n return new ShortcutDescription(\n shortcut.description,\n shortcut.keys.map((key) => {\n return keyMap.get(key) || new KeyDescription('', false);\n })\n );\n });\n }\n}\n\ndeclare module '@glint/environment-ember-loose/registry' {\n export default interface Registry {\n 'Video::VideoStreaming::VideoStreamingToolbar::ShortcutTable': typeof ShortcutTable;\n }\n}\n","import { precompileTemplate } from \"@ember/template-compilation\";\nexport default precompileTemplate(\"\\n
    \\n
    {{tc this \\'newGroupName\\'}}
    \\n
    \\n \\n \\n
    \\n\\n
    \\n
    {{t \\'generic.or\\'}}
    \\n
    \\n\\n
    {{tc this \\'replaceExistingGroup\\'}}
    \\n
    \\n \\n \\n
    \\n
    \\n\\n\",{ moduleName: \"customer-site/components/modals/video/save-camera-group/index.hbs\" })","/* import __COLOCATED_TEMPLATE__ from './index.hbs'; */\nimport Component from '@glimmer/component';\nimport { computed, action } from '@ember/object';\nimport { inject as service } from '@ember/service';\nimport { CreateNewGroup, OverwriteExistingGroup } from 'customer-site/enums/TrackedEvent';\nimport { intlPath } from '@adc/i18n/path';\nimport DropdownSelectItem from '@adc/ui-components/utils/dropdown-select-item';\nimport { updateCameraOrderFromCameras } from '../../../../models/video/camera-group';\n\nimport './_style.scss';\nimport type ADCIntlService from '@adc/i18n/services/adc-intl';\nimport type ModalService from '@adc/ui-components/services/modals';\nimport type NotificationManager from '@adc/ui-components/services/notification-manager';\nimport type Store from '@ember-data/store';\nimport type CameraGroup from 'customer-site/models/video/camera-group';\nimport type Stats from 'customer-site/services/stats';\n\ninterface SaveCameraGroupArgs {\n model: {\n cameraIds?: string[];\n cameraGroups?: CameraGroup[];\n cameraGroupId: string;\n groupSaved(groupId: string, isNewGroup: boolean): void;\n };\n}\n\n/**\n * @classdesc\n * Displays a modal for creating a new camera-group model object or overwriting a previous one.\n */\n@intlPath({ path: 'modals/video/save-camera-group' })\nexport default class SaveCameraGroup extends Component {\n @service declare store: Store;\n @service declare intl: ADCIntlService;\n @service declare notificationManager: NotificationManager;\n @service declare stats: Stats;\n @service declare modals: ModalService;\n\n /**\n * The user input group name.\n */\n groupName?: string;\n\n /**\n * The user selected camera group id.\n */\n selectedCameraGroupId = this.args.model.cameraGroupId;\n\n /**\n * The dropdown camera groups.\n */\n @computed('args.model.cameraGroups.[]')\n get cameraGroupItems(): DropdownSelectItem[] {\n return (this.args.model.cameraGroups ?? []).map(({ id, name }) =>\n DropdownSelectItem.create({\n name,\n value: id\n })\n );\n }\n\n /**\n * Attempts to save the group.\n */\n private async saveGroup(cameraGroup?: CameraGroup, isNewGroup = false): Promise {\n const { intl, notificationManager } = this,\n { model } = this.args,\n { cameraIds } = model;\n\n if (!cameraIds?.length) {\n console.warn('cameraIds object not passed into the model');\n return;\n }\n\n const cameras = cameraIds.map((id) => this.store.peekRecord('video/devices/camera', id));\n\n if (!cameraGroup || !cameras.length) {\n console.warn('camera or cameraGroup could not be found');\n return;\n }\n\n cameraGroup.set('cameras', cameras);\n updateCameraOrderFromCameras(cameraGroup);\n\n try {\n await cameraGroup.save();\n notificationManager.addSuccess(intl.tc(this, 'saveSuccess'));\n model.groupSaved?.(cameraGroup.id, isNewGroup);\n this.modals.closeModal();\n } catch (ex) {\n notificationManager.addError(intl.tc(this, 'saveError'));\n }\n }\n\n /**\n * Overwrites the selected group.\n */\n @action async overwriteGroup(): Promise {\n const cameraGroup = await this.store.findRecord('video/camera-group', this.selectedCameraGroupId);\n\n this.stats.logEvent(OverwriteExistingGroup);\n\n await this.saveGroup(cameraGroup, false);\n }\n\n /**\n * Creates a new group.\n */\n @action async createNewGroup(): Promise {\n const cameraGroup = this.store.createRecord('video/camera-group', {\n name: this.groupName\n });\n\n this.stats.logEvent(CreateNewGroup);\n\n await this.saveGroup(cameraGroup, true);\n }\n}\n\ndeclare module '@glint/environment-ember-loose/registry' {\n export default interface Registry {\n 'Modals::Video::SaveCameraGroup': typeof SaveCameraGroup;\n }\n}\n","import { precompileTemplate } from \"@ember/template-compilation\";\nexport default precompileTemplate(\"
    \\n \\n {{!-- template-lint-disable no-pointer-down-event-binding --}}\\n
    \\n {{this.headerText}}\\n \\n
    \\n
    \\n {{#if this.showSearch}}\\n
    \\n \\n
    \\n {{/if}}\\n
    \\n
    \\n {{#each this.shownCameraGroups as |cameraGroupObject|}}\\n {{#if (await cameraGroupObject.isLiveViewMobileExclusive)}}\\n
    \\n \\n
    \\n {{cameraGroupObject.name}}\\n ({{cameraGroupObject.camerasCountDescription}})\\n
    \\n
    \\n {{else}}\\n \\n {{/if}}\\n {{/each}}\\n
    \\n
    \\n {{#each this.shownCameras.cameraObjects key=\\\"id\\\" as |cameraObject|}}\\n {{#if cameraObject.canBeSelected }}\\n
    \\n \\n {{#if @showLocations}}\\n -\\n {{cameraObject.locationDescription}}\\n {{/if}}\\n {{t \\'generic.only\\'}}\\n
    \\n {{else}}\\n
    \\n {{tc this cameraObject.reasonCameraCannotBeSelected description=cameraObject.description}}\\n
    \\n {{/if}}\\n {{/each}}\\n {{#if this.shownCameras.excludedCameraObjects.length}}\\n

    {{tc this \\'excludedCameras\\'}}

    \\n {{#each this.shownCameras.excludedCameraObjects key=\\\"id\\\" as |cameraObject|}}\\n
    \\n {{tc this cameraObject.reasonCameraCannotBeSelected description=cameraObject.description}}\\n
    \\n {{/each}}\\n {{/if}}\\n {{#if this.shownCameras.cameraListIsCutOff}}\\n \\n
    {{tc this \\'searchToSeeMore\\'}}
    \\n {{/if}}\\n
    \\n
    \\n {{#if this.showResetApplyButtons}}\\n
    \\n \\n \\n
    \\n {{/if}}\\n {{#if this.showNewGroupButton}}\\n \\n {{/if}}\\n
    \\n
    \\n\\n\",{ moduleName: \"customer-site/components/video/video-streaming/video-streaming-toolbar/video-streaming-cameras-selector/index.hbs\" })","/* import __COLOCATED_TEMPLATE__ from './index.hbs'; */\nimport Component from '@glimmer/component';\nimport {\n C_KEY,\n addWeakTrapFocusListener,\n removeTrapFocusListener,\n isEnterOrSpaceCode,\n isSpaceCode,\n nodeHandlesKeyboardInput\n} from '@adc/ember-utils/utils/a11y';\nimport { areArraysSame } from '@adc/ember-utils/utils/array';\nimport { isDestroyed } from '@ember/destroyable';\nimport { action, computed, set, setProperties } from '@ember/object';\nimport { or, reads } from '@ember/object/computed';\nimport { inject as service } from '@ember/service';\nimport { htmlSafe } from '@ember/template';\nimport SaveCameraGroupModal from 'customer-site/components/modals/video/save-camera-group/index';\nimport { V_KEY } from 'customer-site/components/video/video-streaming/video-streaming-toolbar/shortcut-table/index';\nimport { Normal as NormalGroup, Location as LocationGroup } from 'customer-site/enums/CameraGroupType';\nimport {\n CameraSelectorApply,\n CameraSelectorClose,\n CameraSelectorGroupSelected,\n CameraSelectorResetSelection,\n CameraSelectorSaveSelection,\n CameraSelectorSingleCamera,\n CameraSelectorToggleCamera\n} from 'customer-site/enums/TrackedEvent';\nimport { intlPath } from '@adc/i18n/path';\nimport { eventFiredWithModifier } from '../../video-streaming-features/index';\n\nimport type { SafeString } from '@ember/template';\nimport './_style.scss';\nimport type { Registry as ServiceRegistry } from '@ember/service';\nimport type CameraGroup from 'customer-site/models/video/camera-group';\nimport type BaseCamera from 'customer-site/models/video/devices/base-camera';\nimport type Camera from 'customer-site/models/video/devices/camera';\n\ninterface VideoStreamingCamerasSelectorArgs {\n Args: {\n activeCameras: Camera[] | null; // The cameras the user is actively looking at\n alwaysShowSearch: boolean; // If we should always show the search feature. Otherwise we show it based on the SEARCH_CAMERA_COUNT\n cameras: Camera[] | null; // Cameras available to select\n cameraId: string | null; // The selected camera id, if any\n cameraGroup?: CameraGroup; // The selected camera group, if any\n cameraGroups: CameraGroup[] | null; // The available camera groups\n cameraGroupId: string | null; // The selected camera group id, if any\n cameraSelectorStatusChange?: (isOpen: boolean) => void; // Action called when the camera selector is opened or closed\n canEditCameraGroups: boolean; // If the current user can edit camera groups\n groupSaved?: (groupId: string, isNewGroup: boolean) => void; // Action called when a group is saved\n isOperatorSite: boolean; // If we are on an operator site\n maxCameraSelectorHeight: number; // The maximum height allotted to the camera-selector.\n selectCameraGroup?: (groupId: string) => void; // Action called when a user selects a camera group\n setNewActiveCameras?: (cameraIds: string[]) => void; // Action called when a user selects a new set of custom cameras\n showLocations: boolean; // Whether we should show the location descriptions for individual cameras or not.\n };\n Element: HTMLDivElement;\n}\n\ntype CameraObject = {\n id: string;\n canBeSelected: boolean;\n description: string;\n locationDescription?: string;\n isSelected: boolean;\n reasonCameraCannotBeSelected: string;\n};\n\ntype LastSelectedGroup = {\n id: string;\n cameraIds: string[];\n};\n\ntype ShownCameraGroup = {\n id: string;\n name: string;\n camerasCountDescription: string;\n isLiveViewMobileExclusive: boolean | Promise;\n isSelected: boolean;\n isLocation: boolean;\n icon: string;\n};\n\ntype ShownCameras = {\n cameraObjects: CameraObject[];\n excludedCameraObjects: CameraObject[];\n cameraListIsCutOff: boolean;\n};\n\nexport const NEW_GROUP_BUTTON_HEIGHT = 45,\n RESET_APPLY_BUTTONS_HEIGHT = 50,\n SEARCH_HEIGHT = 48,\n MAX_SHOWN_CAMERAS = 64;\n\nconst SEARCH_CAMERA_COUNT = 10,\n CAMERA_SELECTOR_CSS = '.cameras-selector-inner',\n CAMERA_SELECTOR_BUTTON_CSS = '.cameras-selector-inner .header';\n\n/**\n * Returns an array of ids for the camera model objects passed in.\n */\nfunction cameraIdsMapped(cameras: BaseCamera[]): string[] {\n if (!cameras) {\n return [];\n }\n\n return cameras.mapBy('id');\n}\n\n/**\n * Gets the correct translation string for why a given camera cannot be selected in the dropdown.\n * If the camera can be selected, this returns undefined.\n */\nfunction getReasonCameraCannotBeSelected(this: VideoStreamingCamerasSelector, camera: Camera): string {\n const isExcludedDueToEE = this.isEscalatedEvents && camera.excludedFromEscalatedEvents,\n isExcludedDueToVV = this.isVisualVerification && camera.excludedFromVisualVerification;\n\n if (isExcludedDueToEE || isExcludedDueToVV) {\n return 'excludedDescription';\n }\n\n if (!camera.supportsLiveView) {\n return 'appOnlyDescription';\n }\n\n return '';\n}\n\n/**\n * Activates an array of cameras on the page.\n */\nfunction activateCameraIds(this: VideoStreamingCamerasSelector, cameraIdsToActivate: string[]): void {\n if (!cameraIdsToActivate) {\n return;\n }\n\n this.args.setNewActiveCameras && this.args.setNewActiveCameras(cameraIdsToActivate);\n}\n\n/**\n * Activates any cameras or groups that are cached, clears the cache, and closes the dropdown.\n */\nfunction closeDropdown(this: VideoStreamingCamerasSelector): void {\n const { cachedCameraIdsToActivate, cachedGroupIdToActivate } = this;\n\n // Select a cached group to activate (if we have it) otherwise activates a custom set of cameras to activate (if we have it).\n if (cachedGroupIdToActivate) {\n this.args.selectCameraGroup && this.args.selectCameraGroup(cachedGroupIdToActivate);\n } else if (cachedCameraIdsToActivate) {\n activateCameraIds.call(this, cachedCameraIdsToActivate);\n }\n\n // And now that we're closing the dropdown we can clear out all the temporary variables back to their initial state.\n clearAllTemporaryVariables.call(this);\n\n this.args.cameraSelectorStatusChange && this.args.cameraSelectorStatusChange(false);\n\n set(this, 'dropdownIsOpen', false);\n}\n\n/**\n * Updates the cache for cached cameras or groups to activate\n */\nfunction saveCachedCamerasOrGroup(\n this: VideoStreamingCamerasSelector,\n newCachedCameras: string[] | null,\n newCachedGroup: string | null\n): void {\n setProperties(this, {\n cachedCameraIdsToActivate: newCachedCameras,\n cachedGroupIdToActivate: newCachedGroup\n });\n}\n\n/**\n * Clears all temporary variables\n */\nfunction clearAllTemporaryVariables(this: VideoStreamingCamerasSelector): void {\n const { trapFocusListenerId, dom, clickOutsideOfMenuListener } = this;\n\n removeTrapFocusListener(trapFocusListenerId || '');\n\n clearCamerasGroupCache.call(this);\n\n dom.removeListener(this, clickOutsideOfMenuListener || '');\n\n set(this, 'filterString', null);\n}\n\n/**\n * Clears the cache for cameras or groups to activate\n */\nfunction clearCamerasGroupCache(this: VideoStreamingCamerasSelector): void {\n saveCachedCamerasOrGroup.call(this, null, null);\n}\n\n/**\n * The handler for the click outside listener.\n */\nfunction clickOutsideOfMenuHandler(this: VideoStreamingCamerasSelector, event: MouseEvent): void {\n const { target } = event,\n dropdownMenu = document.querySelector(CAMERA_SELECTOR_CSS);\n\n if (dropdownMenu && !dropdownMenu.contains(target as Node)) {\n closeDropdown.call(this);\n }\n}\n\n/**\n * The handler for the hot key listener.\n */\nfunction hotKeyHandler(this: VideoStreamingCamerasSelector, event: KeyboardEvent): void {\n const { target, keyCode, shiftKey } = event;\n\n if (nodeHandlesKeyboardInput(target as Node) || eventFiredWithModifier(event)) {\n return;\n }\n\n switch (keyCode) {\n case C_KEY: {\n if (shiftKey) {\n this.clearSelectedCameras();\n return;\n }\n\n const element = document.querySelector(CAMERA_SELECTOR_BUTTON_CSS) as HTMLElement;\n element.focus();\n element.click();\n break;\n }\n case V_KEY:\n if (!this.showNewGroupButton || this.modals.modalIsOpen(SaveCameraGroupModal)) {\n return;\n }\n\n this.onSaveGroup();\n break;\n }\n}\n\n/**\n * @classdesc\n * A camera and camera group selector component\n */\n@intlPath({ path: 'video.video-streaming.video-streaming-toolbar.video-streaming-cameras-selector' })\nexport default class VideoStreamingCamerasSelector extends Component {\n tagName = '';\n\n @service declare intl: ServiceRegistry['adc-intl'];\n @service declare dom: ServiceRegistry['dom'];\n @service declare modals: ServiceRegistry['modals'];\n @service declare stats: ServiceRegistry['stats'];\n @service declare contextManager: ServiceRegistry['context-manager'];\n\n /**\n * The search string to filter devices by (if not null)\n */\n filterString: string | null = null;\n\n /**\n * If the dropdown is currently open\n */\n dropdownIsOpen = false;\n\n /**\n * Camera ids we should activate when the dropdown is closed\n */\n cachedCameraIdsToActivate: string[] | null = null;\n\n /**\n * The group id to activate when the dropdown is closed\n */\n cachedGroupIdToActivate: string | null = null;\n\n /**\n * The listener to trap focus to the dropdown menu.\n */\n trapFocusListenerId?: string;\n\n /**\n * The listener to close the dropdown menu when a click happens outside of it.\n */\n clickOutsideOfMenuListener: string | null = null;\n\n /**\n * The listener for keydown events used for hotkeys.\n */\n hotKeyListener: string | null = null;\n\n /**\n * Information about the camera group which was last selected, if a group is selected\n */\n lastSelectedGroup?: LastSelectedGroup;\n\n /**\n * The search text for filtering devices\n */\n searchText?: string;\n\n /**\n * Is this an Remote Video Monitoring Console session?\n */\n @reads('contextManager.identityModel.isEscalatedEvents')\n declare isEscalatedEvents: boolean;\n\n /**\n * Is this a visual verification session?\n */\n @reads('contextManager.identityModel.isVisualVerification')\n declare isVisualVerification: boolean;\n\n /**\n * The last group id the user is trying to select. Either the cached selection or the active selection, whichever is newer.\n */\n @or('args.cameraGroupId', 'cachedGroupIdToActivate')\n declare latestGroupId: string;\n\n /**\n * If we should show the search input used for filtering devices in the list.\n */\n @computed('args.{alwaysShowSearch,cameras}', 'dropdownIsOpen')\n get showSearch(): boolean {\n const { args, dropdownIsOpen } = this,\n { alwaysShowSearch, cameras } = args;\n\n if (!cameras) {\n return false;\n }\n\n return dropdownIsOpen && (alwaysShowSearch || cameras.length >= SEARCH_CAMERA_COUNT);\n }\n\n /**\n * The camera groups to be shown in the dropdown\n */\n @computed('args.cameraGroups', 'filterString', 'latestGroupId', 'usingCustomCameras')\n get shownCameraGroups(): ShownCameraGroup[] {\n const { args, filterString, latestGroupId, intl, usingCustomCameras } = this,\n { cameraGroups } = args;\n\n if (!cameraGroups) {\n return [];\n }\n\n const shownCameraGroups: ShownCameraGroup[] = [];\n\n cameraGroups.forEach((group) => {\n // TODO: Please refactor this into a task and remove the isDestroyed usage\n if (isDestroyed(group)) {\n return;\n }\n const { cameras, id, name, groupType, isLiveViewMobileExclusive, icon } = group,\n isSelected = id === latestGroupId && !usingCustomCameras;\n\n // If we've got a filter string, remove groups that don't match the filter OR aren't currently selected.\n if (filterString && !isSelected && name && name.toLowerCase().indexOf(filterString) === -1) {\n return;\n }\n\n const camerasCount = cameras?.length || 0;\n\n let camerasCountDescription = intl.t('generic.video.camerasCount', { num: camerasCount });\n\n if (camerasCount > 0 && !cameras.isAny('supportsLiveView')) {\n camerasCountDescription = intl.tc(this, 'appOnlyWithCount', { count: camerasCountDescription });\n }\n\n shownCameraGroups.push({\n id,\n name,\n camerasCountDescription,\n isLiveViewMobileExclusive,\n isSelected,\n isLocation: groupType === LocationGroup,\n icon\n });\n });\n\n return shownCameraGroups;\n }\n\n /**\n * The cameras to be shown on the dropdown.\n */\n @computed('args.{activeCameras,cameras,isOperatorSite}', 'cameraLocations', 'filterString', 'latestCameraIds')\n get shownCameras(): ShownCameras {\n const { args, cameraLocations, filterString, latestCameraIds } = this,\n { activeCameras, cameras, isOperatorSite } = args;\n\n let cameraObjects: CameraObject[] = [];\n const excludedCameraObjects: CameraObject[] = [];\n\n if (!cameras || !latestCameraIds) {\n return {\n cameraObjects,\n excludedCameraObjects,\n cameraListIsCutOff: false\n };\n }\n\n // First lets add the active Cameras to the cameraObjects array, since we want those to appear at the top of the list.\n if (activeCameras) {\n cameraObjects = activeCameras.map((camera) => {\n const { description, id } = camera,\n reasonCameraCannotBeSelected = getReasonCameraCannotBeSelected.call(this, camera),\n canBeSelected = !reasonCameraCannotBeSelected;\n\n return {\n id,\n canBeSelected,\n description,\n locationDescription: cameraLocations.get(id),\n isSelected: latestCameraIds.includes(id),\n reasonCameraCannotBeSelected\n };\n });\n }\n\n const activeCameraIds = cameraObjects.mapBy('id');\n let cameraListIsCutOff = false;\n\n cameras.forEach((camera) => {\n const { description, id } = camera,\n isSelected = latestCameraIds.includes(id);\n\n // If this camera is already in the activeCameras array, it's already in the cameraObjects array. Skip to the next camera.\n if (activeCameraIds.indexOf(id) !== -1) {\n return;\n }\n\n const reasonCameraCannotBeSelected = getReasonCameraCannotBeSelected.call(this, camera),\n canBeSelected = !reasonCameraCannotBeSelected,\n cameraObj: CameraObject = {\n id,\n canBeSelected,\n description,\n locationDescription: cameraLocations.get(id),\n isSelected,\n reasonCameraCannotBeSelected\n };\n\n // If we're on the operator site, we ignore MAX_SHOWN_CAMERAS and show all cameras in the dropdown.\n // However, we want cameras that can't be selected in their own section at the bottom of the dropdown.\n if (isOperatorSite) {\n if (canBeSelected) {\n cameraObjects.push(cameraObj);\n } else {\n excludedCameraObjects.push(cameraObj);\n }\n\n return;\n }\n\n // Always show selected devices, even they don't match a search or would have otherwise been cut off by MAX_SHOWN_CAMERAS.\n // The MAX_SHOWN_CAMERAS limit is a soft limit and can be stretched a bit this way.\n if (isSelected) {\n cameraObjects.push(cameraObj);\n return;\n }\n\n if (filterString) {\n if (description && description.toLowerCase().indexOf(filterString) !== -1) {\n cameraObjects.push(cameraObj);\n }\n\n return;\n }\n\n // Always show devices if they are selected or match a filter search. The MAX_SHOWN_CAMERAS limit is a soft limit and can be stretched a bit this way.\n // Being able to easily de-select selected cameras or search for cameras takes priority over having a list that is not too long.\n if (cameraObjects.length < MAX_SHOWN_CAMERAS) {\n cameraObjects.push(cameraObj);\n return;\n }\n\n cameraListIsCutOff = true;\n });\n\n return {\n cameraObjects,\n excludedCameraObjects,\n cameraListIsCutOff\n };\n }\n\n /**\n * Returns of the mapping for each camera id to its location/system description.\n */\n @computed('args.{cameraGroups,showLocations}')\n get cameraLocations(): Map {\n const { cameraGroups, showLocations } = this.args,\n locations = new Map();\n\n if (!showLocations || !cameraGroups?.length) {\n return locations;\n }\n\n const locationGroups = cameraGroups.filterBy('groupType', LocationGroup);\n\n locationGroups.forEach((group) => {\n group.cameras.forEach((camera) => {\n locations.set(camera.id, group.name);\n });\n });\n\n return locations;\n }\n\n /**\n * The max-height css value string for the selector.\n */\n @computed(\n 'dropdownIsOpen',\n 'args.maxCameraSelectorHeight',\n 'showNewGroupButton',\n 'showSearch',\n 'showResetApplyButtons'\n )\n get cameraSelectorHeightStyle(): SafeString {\n const { dropdownIsOpen, args, showNewGroupButton, showSearch, showResetApplyButtons } = this,\n { maxCameraSelectorHeight } = args;\n\n let styleCss = '';\n\n if (maxCameraSelectorHeight !== undefined) {\n let pixelAmount = 0;\n\n if (dropdownIsOpen) {\n pixelAmount = maxCameraSelectorHeight;\n\n if (showNewGroupButton) {\n pixelAmount -= NEW_GROUP_BUTTON_HEIGHT;\n }\n\n if (showResetApplyButtons) {\n pixelAmount -= RESET_APPLY_BUTTONS_HEIGHT;\n }\n\n if (showSearch) {\n pixelAmount -= SEARCH_HEIGHT;\n }\n }\n\n styleCss = `max-height: ${Math.max(pixelAmount, 0)}px`;\n }\n\n return htmlSafe(styleCss);\n }\n\n /**\n * If we are currently trying to use a custom selection of cameras. The primary purpose for this is for displaying \"X cameras selected\"\n * on the header when this is true VS displaying the name of a group.\n */\n @computed('cachedCameraIdsToActivate', 'args.cameraGroupId', 'lastSelectedGroup')\n get usingCustomCameras(): boolean {\n const { cachedCameraIdsToActivate, args, lastSelectedGroup } = this,\n { cameraGroupId } = args;\n\n // Edge case. If last selected group is null, it means we don't have a currently selected group and never had a previously\n // selected group. This likely happened from refreshing the page after selecting a custom set of cameras.\n if (!lastSelectedGroup) {\n return true;\n }\n\n // User selected a group and didn't make any changes to it yet.\n if (!cachedCameraIdsToActivate && cameraGroupId) {\n return false;\n }\n\n // If we've got both a previously selected group and also cached changes, we need to see if the changes match the previously\n // selected group. IE we selected a group, added a camera, and then removed the one we added.\n return !areArraysSame(lastSelectedGroup.cameraIds, cachedCameraIdsToActivate || []);\n }\n\n /**\n * If the user is selecting some custom cameras from the dropdown.\n */\n @computed('usingCustomCameras', 'dropdownIsOpen', 'latestCameraIds')\n get userIsSelectingCustomCameras(): boolean {\n const { dropdownIsOpen, latestCameraIds, usingCustomCameras } = this;\n\n return usingCustomCameras && dropdownIsOpen && latestCameraIds && !!latestCameraIds.length;\n }\n\n /**\n * If we should enable the RESET button\n * The RESET button is enabled every time the user selects custom cameras, with the exception of if we don't have a last selected group.\n */\n @computed('lastSelectedGroup', 'userIsSelectingCustomCameras')\n get enableResetButton(): boolean {\n const { lastSelectedGroup, userIsSelectingCustomCameras } = this;\n\n return !!lastSelectedGroup && userIsSelectingCustomCameras;\n }\n\n /**\n * If we should enable the APPLY button.\n */\n @computed('cachedCameraIdsToActivate')\n get enableApplyButton(): boolean {\n return !!this.cachedCameraIdsToActivate;\n }\n\n /**\n * If we should show the enable and apply buttons. We hide them if neither of them are enabled (to save screen real estate).\n */\n @computed('dropdownIsOpen', 'enableApplyButton', 'enableResetButton')\n get showResetApplyButtons(): boolean {\n const { dropdownIsOpen, enableApplyButton, enableResetButton } = this;\n\n return dropdownIsOpen && (enableApplyButton || enableResetButton);\n }\n\n /**\n * If we should show the NEW GROUP button.\n * Note that this will never be visible on an operator site (Visual Verification or Remote Video Monitoring Console)\n * canEditCameraGroups will always be false on an operator site\n */\n @computed('userIsSelectingCustomCameras', 'args.canEditCameraGroups')\n get showNewGroupButton(): boolean {\n const { userIsSelectingCustomCameras, args } = this,\n { canEditCameraGroups } = args;\n\n return userIsSelectingCustomCameras && canEditCameraGroups;\n }\n\n /**\n * The last selected collection of camera ids the user is trying to select. Either the cached selection or the active selection, whichever is newer.\n */\n @computed('args.activeCameras', 'cachedCameraIdsToActivate', 'cachedCameraIdsToActivate.[]')\n get latestCameraIds(): string[] {\n return this.cachedCameraIdsToActivate || cameraIdsMapped(this.args.activeCameras || []);\n }\n\n /**\n * The text to display in the header.\n */\n @computed('args.{cameras,cameraId}', 'cameraGroups', 'latestGroupId', 'latestCameraIds', 'usingCustomCameras')\n get headerText(): string {\n const { latestCameraIds, latestGroupId, args, usingCustomCameras, intl } = this,\n { cameras, cameraId, cameraGroups } = args;\n\n if (!usingCustomCameras && latestGroupId) {\n const matchingGroup = cameraGroups?.filterBy('id', latestGroupId).firstObject;\n\n if (!matchingGroup) {\n // It is possible to hit this point for one rendering cycle due to two computed variables updating at the same time.\n return '';\n }\n\n const camerasCountText = intl.t('generic.video.camerasCount', { num: matchingGroup.cameras.length });\n\n return intl.t('generic.twoWordsWithParanthesis', { first: matchingGroup.name, second: camerasCountText });\n }\n\n if ((!latestGroupId && !cameraId) || !latestCameraIds.length) {\n return intl.tc(this, 'selectCamOrGroup');\n }\n\n if (latestCameraIds.length === 1) {\n return cameras?.findBy('id', latestCameraIds[0])?.description || '';\n }\n\n return intl.t('generic.video.camerasSelected', { num: latestCameraIds.length });\n }\n\n /**\n * Clears the selected cameras on the screen to the last known group selection, if it exists.\n */\n @action\n clearSelectedCameras(): void {\n const { lastSelectedGroup, stats } = this;\n\n if (!lastSelectedGroup || !lastSelectedGroup.cameraIds) {\n return;\n }\n\n stats.logEvent(CameraSelectorResetSelection);\n saveCachedCamerasOrGroup.call(this, lastSelectedGroup.cameraIds, lastSelectedGroup.id);\n }\n\n /**\n * When cameraGroups changes we update the last selected group info\n */\n @action\n updateLastSelectedGroup(): void {\n const { cameraGroup } = this.args;\n\n if (cameraGroup && cameraGroup.cameras) {\n set(this, 'lastSelectedGroup', {\n id: cameraGroup.id,\n cameraIds: cameraIdsMapped(cameraGroup.cameras.toArray())\n });\n }\n }\n\n /**\n * Add hot keys and update the selected group when this component is inserted.\n */\n @action\n onInsert(): void {\n this.addHotKeys();\n this.updateLastSelectedGroup();\n }\n\n /**\n * Toggles the dropdown open/closed\n */\n @action\n toggleDropdown(): void {\n if (this.dropdownIsOpen) {\n const exitEventEnum = this.showResetApplyButtons ? CameraSelectorApply : CameraSelectorClose;\n\n this.stats.logEvent(exitEventEnum);\n\n closeDropdown.call(this);\n } else {\n set(this, 'dropdownIsOpen', true);\n this.args.cameraSelectorStatusChange && this.args.cameraSelectorStatusChange(true);\n this.addListenersOnDropdownOpen();\n }\n }\n\n /**\n * Selects a new camera group.\n */\n @action\n onSelectCameraGroup(groupId: string): void {\n this.stats.logEvent(CameraSelectorGroupSelected);\n closeDropdown.call(this);\n this.args.selectCameraGroup && this.args.selectCameraGroup(groupId);\n }\n\n /**\n * selects a camera\n */\n @action\n onSelectCamera(globalDeviceId: string, isChecked: boolean): void {\n const { args, latestCameraIds, stats } = this,\n { activeCameras } = args;\n\n let cachedCameraIdsToActivate = latestCameraIds;\n\n stats.logEvent(CameraSelectorToggleCamera);\n\n if (isChecked) {\n cachedCameraIdsToActivate = cachedCameraIdsToActivate.concat([globalDeviceId]);\n } else {\n cachedCameraIdsToActivate = cachedCameraIdsToActivate.filter((cameraId) => cameraId !== globalDeviceId);\n\n // We need to set this to [] instead of null as having this as [] has different behavior from null. [] means to set it explicitly\n // camera ids to be empty, whereas null means the cache hasn't been set, and the cameras/groups shown will be the ones that are currently active.\n if (!cachedCameraIdsToActivate.length) {\n cachedCameraIdsToActivate = [];\n }\n }\n\n if (areArraysSame(cachedCameraIdsToActivate, cameraIdsMapped(activeCameras || []))) {\n // Clear the cache since the user likely added a camera and then undid their action (or similar)\n clearCamerasGroupCache.call(this);\n return;\n }\n\n saveCachedCamerasOrGroup.call(this, cachedCameraIdsToActivate, null);\n }\n\n /**\n * Selects one camera to activate immediately.\n */\n @action\n onSelectCameraOnly(globalDeviceId: string): void {\n closeDropdown.call(this);\n this.stats.logEvent(CameraSelectorSingleCamera);\n this.args.setNewActiveCameras && this.args.setNewActiveCameras([globalDeviceId]);\n }\n\n /**\n * Opens the modal for creating or overwriting a group\n */\n @action\n onSaveGroup(): void {\n const { args, latestCameraIds, lastSelectedGroup, stats } = this,\n { cameraGroups } = args,\n userCreatedGroups = cameraGroups?.filterBy('groupType', NormalGroup),\n selectedGroupId =\n lastSelectedGroup && userCreatedGroups?.some((group) => group.id === lastSelectedGroup.id)\n ? lastSelectedGroup.id\n : null;\n\n stats.logEvent(CameraSelectorSaveSelection);\n this.modals.showModal(SaveCameraGroupModal, {\n disableBackdropClose: true,\n cameraIds: latestCameraIds,\n cameraGroups: userCreatedGroups,\n cameraGroupId: selectedGroupId,\n groupSaved: (groupId: string, isNewGroup: boolean) => {\n this.args.groupSaved?.(groupId, isNewGroup);\n }\n });\n\n closeDropdown.call(this);\n }\n\n /**\n * Sets the filterString property to filter devices with.\n */\n @action\n filterDevices(search: string): void {\n // Setting to lower case to do a case insensitive search.\n set(this, 'filterString', search.toLowerCase());\n }\n\n /**\n * Adds event listeners to the document when the dropdown menu is opened.\n */\n @action\n addListenersOnDropdownOpen(): void {\n const trapFocusListenerId = addWeakTrapFocusListener(this, {\n scopeSelector: CAMERA_SELECTOR_CSS,\n escapeCallback: this.toggleDropdown,\n treatArrowsAsTabEvents: true,\n oldListenerId: this.trapFocusListenerId || ''\n }),\n clickOutsideOfMenuListener = this.dom.addListener(this, document, 'mousedown', (event: MouseEvent) => {\n clickOutsideOfMenuHandler.call(this, event);\n });\n\n setProperties(this, {\n trapFocusListenerId,\n clickOutsideOfMenuListener\n });\n }\n\n /**\n * Trigger a click on space and enter events.\n */\n @action\n handleSpaceOrEnter(event: KeyboardEvent): void {\n if (isEnterOrSpaceCode(event.code)) {\n (event.target as HTMLElement).click();\n\n if (isSpaceCode(event.code)) {\n event.stopPropagation();\n }\n }\n }\n\n /**\n * Add hotkeys to document when this component is inserted.\n */\n @action\n addHotKeys(): void {\n const hotKeyListener = this.dom.addListener(this, document, 'keydown', (event: KeyboardEvent) => {\n hotKeyHandler.call(this, event);\n });\n\n set(this, 'hotKeyListener', hotKeyListener);\n }\n\n /**\n * Remove hotkeys from document when this component is removed.\n */\n @action\n removeHotKeys(): void {\n this.dom.removeListener(this, this.hotKeyListener || '');\n }\n}\n\ndeclare module '@glint/environment-ember-loose/registry' {\n export default interface Registry {\n 'Video::VideoStreaming::VideoStreamingToolbar::VideoStreamingCamerasSelector': typeof VideoStreamingCamerasSelector;\n }\n}\n","import { precompileTemplate } from \"@ember/template-compilation\";\nexport default precompileTemplate(\"\\n
    {{tc this \\'keyboardShortcuts\\'}}
    \\n\\n
    \\n
    \\n \\n {{#unless @isAvsPage}}\\n \\n \\n \\n {{/unless}}\\n
    \\n {{#unless @isLiveView}}\\n
    \\n \\n {{#unless this.datePickerDisabled}}\\n \\n {{/unless}}\\n {{#if @isAvsPage}}\\n \\n {{/if}}\\n
    \\n {{/unless}}\\n
    \\n\",{ moduleName: \"customer-site/components/video/video-streaming/video-streaming-toolbar/keyboard-shortcuts-popover/index.hbs\" })","/* import __COLOCATED_TEMPLATE__ from './index.hbs'; */\nimport Component from '@glimmer/component';\nimport { reads } from '@ember/object/computed';\nimport { inject as service } from '@ember/service';\nimport { intlPath } from '@adc/i18n/path';\n\nimport './_style.scss';\nimport type { PopoverMenuSignature } from '@adc/ui-components/components/popover-menu';\nimport type IdentityManager from 'customer-site/services/identity-manager';\nimport type { VideoStreamingToolbarShortcuts } from '../index';\n\ntype PopoverMenuArgs = PopoverMenuSignature['Args'];\n\ninterface VideoClipsStorageProgressSignature {\n Element: PopoverMenuSignature['Element'];\n Args: Pick & {\n isLiveView: boolean;\n isAvsPage?: boolean;\n shortcuts: VideoStreamingToolbarShortcuts;\n };\n}\n\n/**\n * @classdesc\n * Component representing the keyboard shortcuts popover.\n */\n@intlPath({ path: 'video/video-streaming/video-streaming-toolbar/keyboard-shortcuts-popover' })\nexport default class KeyboardShortcutsPopover extends Component {\n @service declare identityManager: IdentityManager;\n\n /**\n * Should date picker be disabled?\n */\n @reads('identityManager.identityModel.isVisualVerification')\n declare datePickerDisabled: boolean;\n}\n\ndeclare module '@glint/environment-ember-loose/registry' {\n export default interface Registry {\n 'Video::VideoStreaming::VideoStreamingToolbar::KeyboardShortcutsPopover': typeof KeyboardShortcutsPopover;\n }\n}\n","import { precompileTemplate } from \"@ember/template-compilation\";\nexport default precompileTemplate(\"\\n\\n {{#each @layoutButtons as |btn|}}\\n {{#if btn.visible}}\\n \\n {{/if}}\\n {{/each}}\\n\",{ moduleName: \"customer-site/components/video/video-streaming/video-streaming-toolbar/layouts-popover/index.hbs\" })","/* import __COLOCATED_TEMPLATE__ from './index.hbs'; */\nimport templateOnlyComponent from '@ember/component/template-only';\n\nimport './_style.scss';\nimport type { Placement } from 'popper.js';\nimport type { LayoutPopoverButton } from '..';\nimport type { LayoutType } from '../../video-streaming-features/types';\n\nexport interface LayoutsPopoverSignature {\n Args: {\n anchorSelector: string;\n isOpen: boolean;\n layoutButtons: LayoutPopoverButton[];\n maxHeight: number;\n placement: Placement;\n selectLayout: (layout: LayoutType) => void;\n };\n Element: HTMLDivElement;\n}\n\nconst LayoutsPopover = templateOnlyComponent();\nexport default LayoutsPopover;\n\ndeclare module '@glint/environment-ember-loose/registry' {\n export default interface Registry {\n 'Video::VideoStreaming::VideoStreamingToolbar::LayoutsPopover': typeof LayoutsPopover;\n }\n}\n","import { precompileTemplate } from \"@ember/template-compilation\";\nexport default precompileTemplate(\"
    \\n
    \\n \\n\\n
    \\n\\n \\n
    \\n
    \",{ moduleName: \"customer-site/components/video/video-streaming/video-streaming-toolbar/layout-zoom-features/index.hbs\" })","/* import __COLOCATED_TEMPLATE__ from './index.hbs'; */\nimport Component from '@glimmer/component';\nimport { intlPath } from '@adc/i18n/path';\n\nimport './_style.scss';\nimport type { LayoutZoomAbility } from '../../video-streaming-features/types';\n\ninterface LayoutZoomFeaturesArgs {\n layoutZoomAbility: LayoutZoomAbility | null;\n performLayoutZoom: (isZoomIn: boolean) => void;\n}\n\n/**\n * @classdesc\n * A component for layout zooming ui features (zooming in and out and a tour)\n */\n@intlPath({ path: 'video/video-streaming/video-streaming-toolbar/layout-zoom-features' })\nexport default class LayoutZoomFeatures extends Component {}\n\ndeclare module '@glint/environment-ember-loose/registry' {\n export default interface Registry {\n 'Video::VideoStreaming::VideoStreamingToolbar::LayoutZoomFeatures': typeof LayoutZoomFeatures;\n }\n}\n","import { precompileTemplate } from \"@ember/template-compilation\";\nexport default precompileTemplate(\"\\n\\n\\n\\n\\n {{#if @showHdButton}}\\n \\n {{/if}}\\n\\n {{#if @showLayoutZoomButtons}}\\n \\n \\n {{/if}}\\n\\n \\n\\n {{#each @buttons.screenSizeButtons as |btn|}}\\n \\n {{/each}}\\n\\n {{#if @buttons.kbdShortcutButton}}\\n \\n \\n {{/if}}\\n\",{ moduleName: \"customer-site/components/video/live-video/display-options-dropdown/index.hbs\" })","/* import __COLOCATED_TEMPLATE__ from './index.hbs'; */\nimport Component from '@glimmer/component';\nimport { action } from '@ember/object';\nimport { inject as service } from '@ember/service';\nimport { intlPath } from '@adc/i18n/path';\n\nimport './_style.scss';\nimport type ADCIntlService from '@adc/i18n/services/adc-intl';\nimport type { LayoutZoomAbility } from 'customer-site/components/video/video-streaming/video-streaming-features/types';\nimport type {\n VideoStreamingToolbarButtons,\n VideoStreamingToolbarShortcuts\n} from 'customer-site/components/video/video-streaming/video-streaming-toolbar/index';\n\ninterface DisplayOptionsDropdownArgs {\n isAvsPage?: boolean;\n isLiveView: boolean;\n maxHeight: number;\n showHdButton: boolean;\n shortcuts: VideoStreamingToolbarShortcuts;\n buttons: VideoStreamingToolbarButtons;\n showDropdown: boolean;\n showLayoutZoomButtons: boolean;\n layoutZoomAbility: LayoutZoomAbility | null;\n toggleDropdown: () => void;\n showDropdownShortcuts: boolean;\n toggleDropdownShortcuts: () => void;\n performLayoutZoom: (isZoomIn: boolean) => void;\n}\n\n/**\n * @classdesc\n *\n * Component representing the dropdown with display options that appears on the live view page on narrow screens.\n */\n@intlPath({ path: 'video/live-video/display-options-dropdown' })\nexport default class DisplayOptionsDropdown extends Component {\n @service declare intl: ADCIntlService;\n\n /**\n * Wrapper function to call a button action and then toggle the dropdown.\n */\n @action clickButton(action?: () => void): void {\n action?.();\n this.args.toggleDropdown.call(this);\n }\n}\n\ndeclare module '@glint/environment-ember-loose/registry' {\n export default interface Registry {\n 'Video::LiveVideo::DisplayOptionsDropdown': typeof DisplayOptionsDropdown;\n }\n}\n","import { precompileTemplate } from \"@ember/template-compilation\";\nexport default precompileTemplate(\"\\n
    \\n {{#if @moreThanOneSupportedCamera}}\\n
    \\n \\n
    \\n {{#if this.showManageGroupsButton}}\\n \\n {{/if}}\\n {{/if}}\\n
    \\n\\n \\n \\n
    \\n {{#if this.showHdButton}}\\n
    \\n \\n
    \\n {{/if}}\\n\\n {{#if this.selectedLayoutsPopoverButton}}\\n
    \\n \\n \\n \\n \\n\\n
    \\n \\n
    \\n
    \\n {{/if}}\\n\\n
    \\n {{#each this.screenSizeButtons as |btn|}}\\n \\n {{/each}}\\n
    \\n\\n {{#if this.kbdShortcutButton}}\\n
    \\n \\n
    \\n {{/if}}\\n
    \\n\\n {{!-- This component is display:none by default and made visible on smaller browser sizes --}}\\n \\n\",{ moduleName: \"customer-site/components/video/video-streaming/video-streaming-toolbar/index.hbs\" })","/* import __COLOCATED_TEMPLATE__ from './index.hbs'; */\nimport Component from '@glimmer/component';\nimport { tracked } from '@glimmer/tracking';\nimport {\n B_KEY,\n C_KEY,\n D_KEY,\n E_KEY,\n F_KEY,\n N_KEY,\n S_KEY,\n T_KEY,\n ENTER_KEY,\n EQUALS_KEY,\n SPACE_KEY,\n UP_ARROW_KEY,\n DOWN_ARROW_KEY,\n LEFT_ARROW_KEY,\n RIGHT_ARROW_KEY,\n LEFT_BRACKET_KEY,\n RIGHT_BRACKET_KEY,\n SHIFT_KEY\n} from '@adc/ember-utils/utils/a11y';\nimport { isMobileBrowser } from '@adc/ember-utils/utils/browser-helpers';\nimport { action, computed } from '@ember/object';\nimport { alias, filterBy, reads } from '@ember/object/computed';\nimport { inject as service } from '@ember/service';\nimport { fnEmpty } from '../../../../utils/ember';\nimport {\n MouseScroll,\n V_KEY,\n H_KEY,\n G_KEY,\n A_KEY\n} from 'customer-site/components/video/video-streaming/video-streaming-toolbar/shortcut-table/index';\nimport { ManageCameraGroups } from 'customer-site/enums/TrackedEvent';\nimport { isElementViewable } from 'customer-site/utils/dom';\nimport { getLayoutChangeEventEnum } from 'customer-site/utils/video/wavefront-stats';\nimport { intlPath } from '@adc/i18n/path';\nimport DropdownSelectItem, { UNSELECTED, SELECTED } from '@adc/ui-components/utils/dropdown-select-item';\nimport {\n AutoView,\n HybridView,\n OnePlusFiveView,\n OnePlusSevenView,\n TwoPlusEightView,\n FourPlusTwoPlusFourView\n} from '../video-streaming-features/index';\n\nimport './_style.scss';\nimport type { Registry as ServiceRegistry } from '@ember/service';\nimport type CameraGroup from 'customer-site/models/video/camera-group';\nimport type Camera from 'customer-site/models/video/devices/camera';\nimport type LayoutControl from '../video-streaming-features/layout-control';\nimport type { LayoutProperties, LayoutType, LayoutZoomAbility } from '../video-streaming-features/types';\n\ninterface VideoStreamingToolbarSignature {\n Args: {\n activeCameras: Camera[] | null; // The active cameras within a camera group. Typically this is just the camera group's cameras, but if we have an active searchQuery, this list will contain all matching camera groups. This value is set manually at various points.\n alwaysHideHdButton?: boolean; // If the HD button should always be hidden (usually if its not supported for the page using this)\n alwaysShowSearchInCamerasSelector: boolean; // Whether we should always show the search bar in the video-streaming-cameras-selector\n cameraGroup?: CameraGroup;\n cameraGroups: CameraGroup[] | null; // The camera groups available to select\n cameras: Camera[] | null;\n cameraId: string | null; // The camera id selected, if any\n cameraGroupId: string | null; // The camera group id selected, if any\n cameraSelectorStatusChange: (isOpened: boolean) => void;\n canEditCameraGroups: boolean;\n canViewManageCameraGroups: boolean; // Does the user have permission to view camera groups?\n groupSaved: (groupId: string, isNewGroup: boolean) => void;\n initialSetupDone: boolean; // Whether the setup done in the init is done.\n isAvsPage?: boolean;\n isEnterprise: boolean;\n isFullScreenAllowed: boolean; // Whether the user should be able to enter the full screen display mode.\n isLiveView: boolean; // Is the user currently viewing the live view page?\n isOperatorSite: boolean;\n layoutControl: LayoutControl; // Controller for various layout related methods\n layoutProperties: LayoutProperties; // A collection of simple properties related to the current layout. (Check the video-streaming-features component for the list of properties)\n layoutZoomAbility: LayoutZoomAbility | null;\n manageGroupsRouteId: number;\n moreThanOneSupportedCamera: boolean;\n page?: number;\n performLayoutZoom: (isZoomIn: boolean) => void;\n resetExpandedCamera: () => void; // Resets all cameras to being their initial (unexpanded) state\n selectCameraGroup: (groupId: string) => void;\n setActiveCameras?: (cameras: Camera[]) => void;\n setNewActiveCameras: (cameraIds: string[]) => void;\n setPageNumber: (pageNumber: number) => void;\n showHdButtonFn?: (cameras: Camera[]) => boolean; // The function used to determine if we should show the hd button toggle in the toolbar. This takes in a list of active cameras and returns a bool. By default we just return true.\n toggleFullScreen: () => void;\n toggleHD: () => void; // Toggle between HD and SD\n toggleTheaterMode: () => void;\n updateLayoutType: (layoutType: LayoutType) => void; // Triggers for the page to change layouts\n updatePlayersDimensions: () => void; // Triggers for the page to recalculate the size of the players\n useHdStream: boolean; // Should we currently stream HD or non-HD streams?\n };\n Element: HTMLDivElement;\n}\n\ntype KeyboardShortcut = {\n keys: number[];\n description: string;\n};\n\ntype ButtonInfo = {\n icon: string;\n action: VoidFunction;\n primary?: boolean;\n text: string;\n};\n\ntype KeyInfo = {\n section: number;\n keys: number[];\n textInfo: {\n isGeneric: boolean;\n key: string;\n };\n};\n\nexport type LayoutPopoverButton = {\n icon: string;\n selected?: boolean;\n text: string;\n tooltipText: string;\n value: LayoutType;\n visible: boolean;\n primary?: boolean;\n};\n\nexport type VideoStreamingToolbarButtons = {\n hdButton: ButtonInfo;\n kbdShortcutButton: ButtonInfo | false;\n screenSizeButtons: ButtonInfo[];\n};\n\nexport type VideoStreamingToolbarShortcuts = {\n cameraShortcuts: KeyboardShortcut[];\n playerViewShortcuts: KeyboardShortcut[];\n selectCameraDropdownShortcuts: KeyboardShortcut[];\n playbackControlShortcuts: KeyboardShortcut[];\n datePickerModalShortcuts: KeyboardShortcut[];\n viewerLayoutShortcuts: KeyboardShortcut[];\n avsControlShortcuts: KeyboardShortcut[];\n};\n\n/**\n * Selects the layout type\n */\nfunction selectLayoutType(this: VideoStreamingToolbar, newLayoutType: LayoutType): void {\n const currentLayoutType = this.args.layoutProperties?.layoutType;\n\n if (currentLayoutType === newLayoutType) {\n return;\n }\n\n this.args.updatePlayersDimensions && this.args.updatePlayersDimensions();\n this.args.updateLayoutType && this.args.updateLayoutType(newLayoutType);\n this.stats.logEvent(getLayoutChangeEventEnum(newLayoutType));\n\n // Tell the child component to leave expanded view.\n this.args.resetExpandedCamera && this.args.resetExpandedCamera();\n}\n\n/**\n * 'selection' IDs for the keyInfos array.\n */\nconst CAMERA_SHORTCUTS = 0,\n PLAYER_VIEW_SHORTCUTS = 1,\n PLAYBACK_CONTROL_SHORTCUTS = 2,\n SELECT_CAMERA_DROPDOWN_SHORTCUTS = 3,\n DATE_PICKER_MODAL_SHORTCUTS = 4,\n VIEWER_LAYOUT_SHORTCUTS = 5,\n AVS_CONTROL_SHORTCUTS = 6;\n\n/**\n * Toolbar component for doing video streaming, to be integrated with pages where users can view streaming/playback on multiple cameras.\n */\n@intlPath({ path: 'video.video-streaming.video-streaming-toolbar' })\nexport default class VideoStreamingToolbar extends Component {\n tagName = '';\n\n @service declare ajax: ServiceRegistry['ajax'];\n @service declare contextManager: ServiceRegistry['context-manager'];\n @service declare dom: ServiceRegistry['dom'];\n @service declare intl: ServiceRegistry['adc-intl'];\n @service declare media: ServiceRegistry['media'];\n @service declare stats: ServiceRegistry['stats'];\n @service declare identityManager: ServiceRegistry['identity-manager'];\n\n // region Cameras\n\n /**\n * Does the account have internal beta enabled\n */\n @alias('contextManager.identityModel.hasInternalBetaAccess')\n declare hasInternalBetaAccess: boolean;\n\n /**\n * Whether or not to show the manage/edit groups button.\n */\n @computed('args.{cameraId,cameraGroupId,canViewManageCameraGroups}', 'isOperatorSession')\n get showManageGroupsButton(): boolean {\n return (\n !this.isOperatorSession &&\n (!!this.args.cameraGroupId || !!this.args.cameraId) &&\n this.args.canViewManageCameraGroups\n );\n }\n\n /**\n * The button information for the selected layouts popover button\n */\n @computed(\n 'layoutsPopoverButtons',\n 'args.{activeCameras.length,layoutProperties.layoutType}',\n 'showLayoutsPopover',\n 'isOperatorSession'\n )\n get selectedLayoutsPopoverButton(): ButtonInfo | null {\n const { layoutsPopoverButtons, args, isOperatorSession } = this,\n { activeCameras, layoutProperties } = args,\n { layoutType } = layoutProperties || {};\n\n if (!layoutsPopoverButtons || !layoutsPopoverButtons.length || isOperatorSession) {\n return null;\n }\n\n // dont need to show this layouts button when there is 1 camera because changing the view or zoom level have no impact on that use case.\n if (!activeCameras || activeCameras.length === 1) {\n return null;\n }\n\n const selectedLayoutButton = layoutsPopoverButtons.find((layoutButton) => layoutButton.value === layoutType);\n\n if (!selectedLayoutButton) {\n return null;\n }\n\n return {\n icon: selectedLayoutButton.icon,\n action: () => {\n // Do not copy this deprecated usage. If you see this, please fix it\n // eslint-disable-next-line ember/no-side-effects\n this.showLayoutsPopover = !this.showLayoutsPopover;\n },\n primary: undefined,\n text: selectedLayoutButton.tooltipText\n };\n }\n\n /**\n * An array of button information used for the layouts popover.\n */\n @computed('args.{cameras,isLiveView}', 'args.layoutProperties.{isHybridWide,layoutType}')\n get layoutsPopoverButtons(): LayoutPopoverButton[] {\n const { args, intl } = this,\n { cameras, isLiveView, layoutControl, layoutProperties } = args,\n { isHybridWide, layoutType } = layoutProperties || {},\n tooltipConcatenator = ' ' + intl.t('generic.view'),\n autoText = intl.t('generic.auto'),\n text1plus3 = intl.tc(this, '1plus3'),\n text1plus5 = intl.tc(this, '1plus5'),\n text1plus7 = intl.tc(this, '1plus7'),\n text2plus8 = intl.tc(this, '2plus8'),\n text4plus2plus4 = intl.tc(this, '4plus2plus4');\n\n if (!cameras || !layoutControl) {\n return [];\n }\n\n const cameraCount = cameras.length;\n\n return [\n // Auto/Grid view\n {\n icon: 'view-auto',\n selected: layoutType === AutoView,\n text: autoText,\n tooltipText: autoText + tooltipConcatenator,\n value: AutoView,\n visible: layoutControl.layoutIsAllowedForScenario(AutoView, cameraCount, isLiveView)\n },\n // 1+3, aka hybrid (old name)\n {\n icon: isHybridWide ? 'view-3+1' : 'view-1+3',\n selected: layoutType === HybridView,\n text: text1plus3,\n tooltipText: text1plus3 + tooltipConcatenator,\n value: HybridView,\n visible: layoutControl.layoutIsAllowedForScenario(HybridView, cameraCount, isLiveView)\n },\n // 1+5 view\n {\n icon: 'view-1+5',\n selected: layoutType === OnePlusFiveView,\n text: text1plus5,\n tooltipText: text1plus5 + tooltipConcatenator,\n value: OnePlusFiveView,\n // this button and below buttons are only visible on the live video page\n visible: layoutControl.layoutIsAllowedForScenario(OnePlusFiveView, cameraCount, isLiveView)\n },\n // 1+7 view\n {\n icon: 'view-1+7',\n selected: layoutType === OnePlusSevenView,\n text: text1plus7,\n tooltipText: text1plus7 + tooltipConcatenator,\n value: OnePlusSevenView,\n visible: layoutControl.layoutIsAllowedForScenario(OnePlusSevenView, cameraCount, isLiveView)\n },\n // 2+8 view\n {\n icon: 'view-2+8',\n selected: layoutType === TwoPlusEightView,\n text: text2plus8,\n tooltipText: text2plus8 + tooltipConcatenator,\n value: TwoPlusEightView,\n visible: layoutControl.layoutIsAllowedForScenario(TwoPlusEightView, cameraCount, isLiveView)\n },\n // 4+2+4 view\n {\n icon: 'view-4+2+4',\n selected: layoutType === FourPlusTwoPlusFourView,\n text: text4plus2plus4,\n tooltipText: text4plus2plus4 + tooltipConcatenator,\n value: FourPlusTwoPlusFourView,\n visible: layoutControl.layoutIsAllowedForScenario(FourPlusTwoPlusFourView, cameraCount, isLiveView)\n }\n ];\n }\n\n // endregion\n\n // region Toolbar\n\n /**\n * Represents the HD button on the toolbar.\n */\n @computed('args.{toggleHD,useHdStream}')\n get hdButton(): ButtonInfo {\n return {\n icon: 'video-layout-hd',\n action: () => this.args.toggleHD && this.args.toggleHD(),\n primary: this.args.useHdStream,\n text: this.intl.t('generic.hd')\n };\n }\n\n /**\n * The max height for popovers.\n */\n @tracked maxPopoverHeight = 0;\n\n /**\n * Whether we show the dropdown.\n */\n @tracked showDropdown = false;\n\n /**\n * Whether we show the keyboard shortcut within the dropdown menu.\n */\n @tracked showDropdownShortcuts = false;\n\n /**\n * Whether or not the keyboard shortcuts popover is visible.\n */\n @tracked showShortcuts = false;\n\n /**\n * If the layouts popover is visible.\n */\n @tracked showLayoutsPopover = false;\n\n /**\n * Toggles dropdown.\n */\n @action toggleDropdown(): void {\n this.showDropdown = !this.showDropdown;\n }\n\n /**\n * Toggles keyboard shortcut popover within the dropdown.\n */\n @action toggleDropdownShortcuts(): void {\n // Close the dropdown before opening the shortcuts popover.\n this.toggleDropdown.call(this);\n this.showDropdownShortcuts = !this.showDropdownShortcuts;\n }\n\n /**\n * Toggles keyboard shortcut popover.\n */\n @action toggleShortcut(): void {\n this.showShortcuts = !this.showShortcuts;\n }\n\n /**\n * Triggered on resize.\n */\n @action onResize(): void {\n // If a popover is open and its anchor isn't viewable, close it.\n if (this.showShortcuts) {\n if (!isElementViewable('.keyboard-shortcut-button')) {\n this.showShortcuts = false;\n }\n } else if (this.showDropdown || this.showDropdownShortcuts) {\n if (!isElementViewable('.display-options-dropdown-anchor')) {\n this.showDropdown = false;\n this.showDropdownShortcuts = false;\n }\n }\n }\n\n /**\n * Represents the Keyboard Shortcut button on the toolbar.\n */\n get kbdShortcutButton(): ButtonInfo | false {\n if (isMobileBrowser()) {\n return false;\n }\n\n return {\n icon: 'keyboard',\n action: () => {\n this.toggleShortcut();\n },\n primary: undefined,\n text: this.intl.tc(this, 'keyboardShortcuts')\n };\n }\n\n /**\n * Keyboard shortcuts. These need to be kept in-sync with the shortcuts\n * set up in the various video-streaming components.\n */\n get keyInfos(): KeyInfo[] {\n return [\n { section: CAMERA_SHORTCUTS, keys: [E_KEY], textInfo: { isGeneric: false, key: 'expandRestore' } },\n { section: CAMERA_SHORTCUTS, keys: [N_KEY], textInfo: { isGeneric: false, key: 'nextCamera' } },\n { section: CAMERA_SHORTCUTS, keys: [B_KEY], textInfo: { isGeneric: false, key: 'previousCamera' } },\n { section: PLAYER_VIEW_SHORTCUTS, keys: [T_KEY], textInfo: { isGeneric: false, key: 'theaterMode' } },\n { section: PLAYER_VIEW_SHORTCUTS, keys: [F_KEY], textInfo: { isGeneric: false, key: 'fullScreenMode' } },\n {\n section: PLAYBACK_CONTROL_SHORTCUTS,\n keys: [SPACE_KEY],\n textInfo: { isGeneric: false, key: 'playPause' }\n },\n {\n section: PLAYBACK_CONTROL_SHORTCUTS,\n keys: [LEFT_ARROW_KEY],\n textInfo: { isGeneric: false, key: 'seekBack30s' }\n },\n {\n section: PLAYBACK_CONTROL_SHORTCUTS,\n keys: [RIGHT_ARROW_KEY],\n textInfo: { isGeneric: false, key: 'seekForward30s' }\n },\n {\n section: PLAYBACK_CONTROL_SHORTCUTS,\n keys: [EQUALS_KEY],\n textInfo: { isGeneric: false, key: 'speedReset' }\n },\n {\n section: PLAYBACK_CONTROL_SHORTCUTS,\n keys: [LEFT_BRACKET_KEY],\n textInfo: { isGeneric: false, key: 'reduceSpeed' }\n },\n {\n section: PLAYBACK_CONTROL_SHORTCUTS,\n keys: [RIGHT_BRACKET_KEY],\n textInfo: { isGeneric: false, key: 'increaseSpeed' }\n },\n {\n section: SELECT_CAMERA_DROPDOWN_SHORTCUTS,\n keys: [C_KEY],\n textInfo: { isGeneric: false, key: 'openClose' }\n },\n {\n section: SELECT_CAMERA_DROPDOWN_SHORTCUTS,\n keys: [UP_ARROW_KEY],\n textInfo: { isGeneric: false, key: 'navUp' }\n },\n {\n section: SELECT_CAMERA_DROPDOWN_SHORTCUTS,\n keys: [DOWN_ARROW_KEY],\n textInfo: { isGeneric: false, key: 'navDown' }\n },\n {\n section: SELECT_CAMERA_DROPDOWN_SHORTCUTS,\n keys: [SPACE_KEY],\n textInfo: { isGeneric: true, key: 'generic.select' }\n },\n {\n section: SELECT_CAMERA_DROPDOWN_SHORTCUTS,\n keys: [V_KEY],\n textInfo: { isGeneric: true, key: 'generic.save' }\n },\n {\n section: SELECT_CAMERA_DROPDOWN_SHORTCUTS,\n keys: [SHIFT_KEY, C_KEY],\n textInfo: { isGeneric: true, key: 'generic.reset' }\n },\n { section: DATE_PICKER_MODAL_SHORTCUTS, keys: [D_KEY], textInfo: { isGeneric: false, key: 'openClose' } },\n {\n section: DATE_PICKER_MODAL_SHORTCUTS,\n keys: [ENTER_KEY],\n textInfo: { isGeneric: false, key: 'goToSelectedTime' }\n },\n {\n section: VIEWER_LAYOUT_SHORTCUTS,\n keys: [SHIFT_KEY, UP_ARROW_KEY],\n textInfo: { isGeneric: true, key: 'generic.enlarge' }\n },\n {\n section: VIEWER_LAYOUT_SHORTCUTS,\n keys: [SHIFT_KEY, DOWN_ARROW_KEY],\n textInfo: { isGeneric: true, key: 'generic.shrink' }\n },\n {\n section: VIEWER_LAYOUT_SHORTCUTS,\n keys: [SHIFT_KEY, MouseScroll],\n textInfo: { isGeneric: true, key: 'generic.zoom' }\n },\n {\n section: VIEWER_LAYOUT_SHORTCUTS,\n keys: [SHIFT_KEY, RIGHT_ARROW_KEY],\n textInfo: { isGeneric: true, key: 'generic.pagination.next' }\n },\n {\n section: VIEWER_LAYOUT_SHORTCUTS,\n keys: [SHIFT_KEY, LEFT_ARROW_KEY],\n textInfo: { isGeneric: true, key: 'generic.pagination.previous' }\n },\n {\n section: AVS_CONTROL_SHORTCUTS,\n keys: [SHIFT_KEY, H_KEY],\n textInfo: { isGeneric: true, key: 'generic.skipToNext' }\n },\n {\n section: AVS_CONTROL_SHORTCUTS,\n keys: [SHIFT_KEY, G_KEY],\n textInfo: { isGeneric: true, key: 'generic.skipToPrevious' }\n },\n {\n section: AVS_CONTROL_SHORTCUTS,\n keys: [SHIFT_KEY, S_KEY],\n textInfo: { isGeneric: false, key: 'returnToSvr' }\n },\n {\n section: AVS_CONTROL_SHORTCUTS,\n keys: [SHIFT_KEY, A_KEY],\n textInfo: { isGeneric: false, key: 'editFilters' }\n }\n ];\n }\n\n /**\n * Returns keyboard shortcuts formatted for the shortcut-table component.\n */\n getKeySection(keyType: number): KeyboardShortcut[] {\n return this.keyInfos.filterBy('section', keyType).map((keyInfo) => {\n return {\n keys: keyInfo.keys,\n description: keyInfo.textInfo.isGeneric\n ? this.intl.t(keyInfo.textInfo.key)\n : this.intl.tc(this, keyInfo.textInfo.key)\n };\n });\n }\n\n /**\n * Camera-specific keyboard shortcuts. Needs to be kept in-sync with\n * the shortcuts set up in the video-streaming-features component.\n */\n get cameraShortcuts(): KeyboardShortcut[] {\n return this.getKeySection(CAMERA_SHORTCUTS);\n }\n\n /**\n * Player-view specific keyboard shortcuts. Needs to be kept in-sync\n * with the shortcuts set up in the video-streaming-features component.\n */\n get playerViewShortcuts(): KeyboardShortcut[] {\n return this.getKeySection(PLAYER_VIEW_SHORTCUTS);\n }\n\n /**\n * Player Control specific keyboard shortcuts. Needs to be kept in-sync\n * with the shortcuts set up in the playback-features component.\n */\n get playbackControlShortcuts(): KeyboardShortcut[] {\n return this.getKeySection(PLAYBACK_CONTROL_SHORTCUTS);\n }\n\n /**\n * Select Camera Dropdown specific keyboard shortcuts. Needs to be kept\n * in-sync with the shortcuts set up in the video-streaming-cameras-selector\n */\n get selectCameraDropdownShortcuts(): KeyboardShortcut[] {\n return this.getKeySection(SELECT_CAMERA_DROPDOWN_SHORTCUTS);\n }\n\n /**\n * Date Picker Modal specific keyboard shortcuts. Needs to be kept in-sync\n * with the shortcuts set up in the date-picker modal component.\n */\n get datePickerModalShortcuts(): KeyboardShortcut[] {\n return this.getKeySection(DATE_PICKER_MODAL_SHORTCUTS);\n }\n\n /**\n * Viewer Layout (Layouts Popover) specific keyboard shortcuts. Needs to be kept\n * in-sync with the shortcuts set up in the video-streaming-cameras-selector\n */\n get viewerLayoutShortcuts(): KeyboardShortcut[] {\n return this.getKeySection(VIEWER_LAYOUT_SHORTCUTS);\n }\n\n /**\n * Keyboard shortcuts for use with Advanced Video Search\n */\n get avsControlShortcuts(): KeyboardShortcut[] {\n return this.getKeySection(AVS_CONTROL_SHORTCUTS);\n }\n\n /**\n * An object for all shortcuts.\n */\n get shortcuts(): VideoStreamingToolbarShortcuts {\n const {\n cameraShortcuts,\n playerViewShortcuts,\n selectCameraDropdownShortcuts,\n playbackControlShortcuts,\n datePickerModalShortcuts,\n viewerLayoutShortcuts,\n avsControlShortcuts\n } = this;\n return {\n cameraShortcuts,\n playerViewShortcuts,\n selectCameraDropdownShortcuts,\n playbackControlShortcuts,\n datePickerModalShortcuts,\n viewerLayoutShortcuts,\n avsControlShortcuts\n };\n }\n\n /**\n * An object for all toolbar buttons.\n */\n get buttons(): VideoStreamingToolbarButtons {\n const { hdButton, kbdShortcutButton, screenSizeButtons } = this;\n return {\n hdButton,\n kbdShortcutButton,\n screenSizeButtons\n };\n }\n\n /**\n * Component rendered on a Visual Verification page\n */\n @reads('identityManager.identityModel.isVisualVerification')\n declare isOperatorSession: boolean;\n\n /**\n * Should we display the HD toggle button?\n * We will not display it if all cameras on this page do not use it because the stream quality does not change.\n */\n @computed('args.{activeCameras,alwaysHideHdButton,initialSetupDone,showHdButtonFn}')\n get showHdButton(): boolean {\n const { args } = this,\n { activeCameras, alwaysHideHdButton, initialSetupDone, showHdButtonFn } = args;\n\n return (\n !alwaysHideHdButton &&\n initialSetupDone &&\n !!activeCameras?.length &&\n !!showHdButtonFn?.call(this, activeCameras)\n );\n }\n\n /**\n * Buttons that deal with screen size, i.e. theater mode and full screen.\n */\n @computed('args.layoutProperties.{isFullScreen,isTheaterMode}', 'args.isFullScreenAllowed', 'isOperatorSession')\n get screenSizeButtons(): ButtonInfo[] {\n const { args } = this,\n { isFullScreenAllowed, layoutProperties, toggleFullScreen, toggleTheaterMode } = args,\n { isFullScreen, isTheaterMode } = layoutProperties || {};\n\n const makeButton = (translationKey: string, iconType: string, fnAction?: VoidFunction) => ({\n text: this.intl.t(`generic.video.videoStreamingPlayers.${translationKey}`),\n icon: `screen-${iconType}`,\n action: () => fnAction && fnAction()\n });\n\n const buttons = [];\n // Theater Mode is disabled for the operators in order to have less distraction on the screen and focus on assessing the situation\n if (!this.isOperatorSession) {\n const theaterText = isTheaterMode ? 'exitTheaterMode' : 'theaterMode',\n theaterIcon = isTheaterMode ? 'exit-full' : 'theater';\n buttons.push(makeButton(theaterText, theaterIcon, toggleTheaterMode));\n }\n\n // Full screen mode isn't available on mobile/tablet\n if (isFullScreenAllowed && !isMobileBrowser()) {\n const fullScreenText = isFullScreen ? 'exitFullScreen' : 'fullScreen',\n fullScreenIcon = isFullScreen ? 'exit-full' : 'fullscreen';\n\n buttons.push(makeButton(fullScreenText, fullScreenIcon, toggleFullScreen));\n }\n\n return buttons;\n }\n\n // endregion\n\n // region Camera Layout and Single View\n\n /**\n * Whether the latest full screen change was made by the toolbar button or by the user's keyboard.\n */\n fullScreenChangeMadeByButton = false;\n\n /**\n * Whether we are in an RTL language.\n */\n @alias('locale.isRtl')\n declare isRtl: boolean;\n\n // endregion\n\n // region Individual Camera Dropdown\n\n /**\n * All selectable cameras within the current context.\n */\n @filterBy('args.cameras', 'selectableInDropdown', true)\n declare selectableDropdownCameras: Camera[];\n\n /**\n * Dropdown items for the individual camera dropdown.\n */\n @computed('args.cameras')\n get dropdownCameras(): DropdownSelectItem[] {\n return [\n DropdownSelectItem.create({\n name: this.intl.t('generic.devices.cameras'),\n isSelectable: false,\n showAllNoneSelectors: true,\n subitems: this.args.cameras?.map((camera) =>\n DropdownSelectItem.create({\n name: camera.description,\n value: camera.id,\n state: camera.selectableInDropdown ? SELECTED : UNSELECTED,\n disabled: !camera.selectableInDropdown\n })\n )\n })\n ];\n }\n\n // endregion\n\n // region Styling and Page Dimensions\n\n /**\n * The function called when pressing the theater mode button.\n */\n togglePlayerTheaterMode = fnEmpty;\n\n /**\n * The function called when pressing the full screen button.\n */\n togglePlayerFullScreenMode = fnEmpty;\n\n // endregion\n\n @action selectLayout(layoutValue: LayoutType): void {\n selectLayoutType.call(this, layoutValue);\n this.showLayoutsPopover = false;\n }\n\n /**\n * Transitions to the manage camera groups page.\n */\n @action transitionToManagePage(): void {\n if (!this.args.manageGroupsRouteId) {\n return;\n }\n\n // TODO: This ignore is an existing deprecation that must be refactored, do not copy this usage\n // eslint-disable-next-line @adc/ember/no-context-manager-transition\n this.contextManager.transitionToRouteId(this.args.manageGroupsRouteId);\n }\n\n @action onManageCameraGroupsClick(): void {\n this.stats.logEvent(ManageCameraGroups);\n this.transitionToManagePage();\n }\n\n /**\n * Camera filter changed action. Sets active cameras to those selected in the dropdown.\n *\n */\n @action onCameraFilterChange(): void {\n const selectedCameras = this.dropdownCameras[0].subitems\n .filter(({ disabled, state }) => !disabled && state === SELECTED)\n .mapBy('value');\n\n const camerasToDisplay = this.selectableDropdownCameras.filter((camera) => selectedCameras.includes(camera.id));\n\n this.args.setActiveCameras && this.args.setActiveCameras(camerasToDisplay);\n this.args.setPageNumber && this.args.setPageNumber(1);\n }\n}\n\ndeclare module '@glint/environment-ember-loose/registry' {\n export default interface Registry {\n 'Video::VideoStreaming::VideoStreamingToolbar': typeof VideoStreamingToolbar;\n }\n}\n","import { helper } from '@ember/component/helper';\n\nexport interface ExistsHelperSignature {\n Args: {\n Positional: any[];\n };\n Return: boolean;\n}\n\n/**\n * Template helper for determining if all input values are defined.\n */\nexport function exists(params: ExistsHelperSignature['Args']['Positional']): ExistsHelperSignature['Return'] {\n return params.every((p) => typeof p != 'undefined' && p !== null);\n}\n\nexport default helper(exists);\n\ndeclare module '@glint/environment-ember-loose/registry' {\n export default interface Registry {\n /** Template helper for determining if all input values are defined. */\n exists: typeof exists;\n }\n}\n","import { action, computed } from '@ember/object';\nimport { inject as service } from '@ember/service';\nimport { SvrRecordingSchedule } from 'customer-site/enums/RuleCatalogItemType';\nimport { VideoLocalSchedule as VideoLocalScheduleDisplayType } from 'customer-site/enums/RuleDisplayType';\nimport { StreamUsage } from 'customer-site/enums/StreamUsage';\nimport { getCaughtError } from 'customer-site/utils/general';\nimport {\n EmberEnterpriseVideoAdvancedVideoSearch,\n EmberVideoAdvancedVideoSearch,\n VideoAddSvrRecordingSchedule\n} from '../../enums/CustomerPageUrl';\nimport { videoScheduleTransitionFunction } from '../../utils/video/general';\nimport BasePlaybackController from '../base-playback-controller';\n\nimport type ModalService from '@adc/ui-components/services/modals';\nimport type Store from '@ember-data/store';\nimport type ContextManager from 'customer-site/services/context-manager';\n\n/**\n * @classdesc\n * Controller for the svr-timeline page.\n */\nexport default class SvrTimelineController extends BasePlaybackController {\n @service declare modals: ModalService;\n @service declare contextManager: ContextManager;\n @service declare media: ADCResponsiveMediaService;\n @service declare store: Store;\n\n declare model: any; // Please replace this 'any' with the actual model type!\n\n /** @override */\n playbackType = StreamUsage.Svr;\n\n /**\n * Determines if we should show a link to the Advanced Video Search page.\n */\n @computed('contextManager.isEnterprise', 'media.isMobile')\n get enableAdvancedVideoSearch(): boolean {\n const advancedVideoSearchRoute = this.contextManager.isEnterprise\n ? EmberEnterpriseVideoAdvancedVideoSearch\n : EmberVideoAdvancedVideoSearch;\n // Do not copy this deprecated usage. If you see this, please fix it\n // eslint-disable-next-line @adc/ember/no-context-manager-get-route\n return !this.media.isMobile && !!this.contextManager.getRouteItem(advancedVideoSearchRoute);\n }\n\n /**\n * Navigates to the Add Recording Schedules route.\n */\n @action\n async goToAddSchedulesRoute(): Promise {\n const { contextManager, modals, model, store } = this,\n { svrs } = model,\n // Do not copy this deprecated usage. If you see this, please fix it\n // eslint-disable-next-line @adc/ember/no-context-manager-get-route\n availableRoutesIds = [VideoAddSvrRecordingSchedule].filter((id) => contextManager.getRouteItem(id));\n\n store\n .query('automation/rules/ruleSuggestion', { type: VideoLocalScheduleDisplayType })\n .then((localScheduleSuggestions) => {\n const svrSchedules = localScheduleSuggestions.filter(\n (suggestion) => suggestion.type === SvrRecordingSchedule\n ),\n showSvrScheduleModalFunction = videoScheduleTransitionFunction.call(\n this,\n availableRoutesIds,\n contextManager,\n modals,\n svrs,\n null,\n svrSchedules\n );\n\n if (!showSvrScheduleModalFunction) {\n console.warn('No suggestions found for SVR schedule creation.');\n return;\n }\n\n showSvrScheduleModalFunction.call(this);\n })\n .catch((error) => {\n const errMsg = getCaughtError(error);\n console.error(errMsg);\n });\n }\n}\n\n// DO NOT DELETE: this is how TypeScript knows how to look up your controllers.\ndeclare module '@ember/controller' {\n interface Registry {\n 'video/svr-timeline': SvrTimelineController;\n }\n}\n","import { inject as service } from '@ember/service';\nimport AdcBaseRoute from 'customer-site/classes/base-route';\nimport {\n EmberSDCard,\n EmberVideoThumbnailSearch,\n EmberEnterpriseVideoThumbnailSearch\n} from 'customer-site/enums/CustomerPageUrl';\nimport { getContextAwareSvrTimelinePage } from 'customer-site/video/svr-timeline/route';\nimport { getQueryParam } from '@adc/app-infrastructure/routes/base-route';\nimport { differenceInSeconds, minutesToSeconds, startOfMinute } from 'date-fns';\n\nimport type IntervalsGroup from 'customer-site/models/video/intervals-group';\nimport type SdCardThumbnailEndpoint from 'customer-site/models/video/sd-card-thumbnail-endpoint';\nimport type SvrThumbnailEndpoint from 'customer-site/models/video/svr-thumbnail-endpoint';\nimport type IdentityManager from 'customer-site/services/identity-manager';\n\nexport interface VideoThumbnailSearchRouteModel {\n /**Model for the svr/sd card thumbnail endpoint.*/\n thumbnailEndpoint: SvrThumbnailEndpoint | SdCardThumbnailEndpoint;\n /**Is this thumbnail search for an SD card camera?*/\n isSdCard: boolean;\n /**The time on the timeline before navigating to this page. Thumbnail search will start 24 hours before this time by default. */\n timeUtc: Date;\n /**Model containing interval data for the camera being serached on */\n intervals: IntervalsGroup;\n /**Id of the camera being searched on */\n cameraId: string;\n}\n\ninterface ThumbnailSearchQueryParams {\n /**The id of the camera we want to do thumbnail search for.*/\n id_camera: string;\n /**The time on the timeline before navigating to this page. Thumbnail search will start 24 hours before this time by default. */\n time: Date;\n /**Did we come from the onboard timeline? */\n isSdCard: boolean;\n}\n\nexport function getContextAwareThumbnailSearchPage(isEnterprise: boolean): number {\n return isEnterprise ? EmberEnterpriseVideoThumbnailSearch : EmberVideoThumbnailSearch;\n}\n\nexport default class VideoThumbnailSearchRoute extends AdcBaseRoute {\n @service declare identityManager: IdentityManager;\n\n /** @override */\n routeId = EmberVideoThumbnailSearch;\n\n queryParams = {\n time: getQueryParam('date'),\n isSdCard: getQueryParam('boolean')\n };\n\n async model(params: ThumbnailSearchQueryParams): Promise {\n const time = params.time ?? startOfMinute(new Date());\n const isSdCard = params.isSdCard ?? false;\n\n const deviceName = isSdCard ? 'sd-card-camera' : 'camera';\n const camera = await this.store.findRecord(`video/devices/${deviceName}`, params.id_camera);\n\n if (!camera.supportsThumbnailSearch) {\n this.onError(this.intl.tc(this, 'cameraNotSupported'), isSdCard);\n }\n\n const thumbnailEndpointPromise = camera.thumbnailEndpoint;\n const videoSourcePromise = camera.recordedVideoSource;\n const [thumbnailEndpoint, videoSource] = await Promise.all([thumbnailEndpointPromise, videoSourcePromise]);\n\n return {\n thumbnailEndpoint: thumbnailEndpoint,\n isSdCard,\n timeUtc: time,\n intervals: await videoSource.intervals,\n cameraId: params.id_camera\n };\n }\n\n afterModel(model: VideoThumbnailSearchRouteModel): void {\n if (!model.intervals) {\n this.onError(this.intl.tc(this, 'notEnoughFootage'), model.isSdCard);\n return;\n }\n const { earliestRecord, latestRecord } = model.intervals;\n if (\n !earliestRecord ||\n !latestRecord ||\n differenceInSeconds(latestRecord, earliestRecord) < minutesToSeconds(3)\n ) {\n this.onError(this.intl.tc(this, 'notEnoughFootage'), model.isSdCard);\n }\n }\n\n /**\n * Handles showing an error message and redirecting away from page.\n * @param message Error message to display\n * @returns\n */\n onError(message: string, isSdCard: boolean): void {\n const timelineRoute = isSdCard\n ? EmberSDCard\n : getContextAwareSvrTimelinePage(this.identityManager.isEnterprise);\n this.notificationManager.addNotification(message, 'issue', undefined, 0, true, false, 'error');\n this.contextManager.transitionBackToMobileAppOrPreviousRoute(timelineRoute);\n return;\n }\n}\n","import toDate from \"../toDate/index.js\";\nimport requiredArgs from \"../_lib/requiredArgs/index.js\";\n/**\n * @name startOfMinute\n * @category Minute Helpers\n * @summary Return the start of a minute for the given date.\n *\n * @description\n * Return the start of a minute for the given date.\n * The result will be in the local timezone.\n *\n * @param {Date|Number} date - the original date\n * @returns {Date} the start of a minute\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // The start of a minute for 1 December 2014 22:15:45.400:\n * const result = startOfMinute(new Date(2014, 11, 1, 22, 15, 45, 400))\n * //=> Mon Dec 01 2014 22:15:00\n */\n\nexport default function startOfMinute(dirtyDate) {\n requiredArgs(1, arguments);\n var date = toDate(dirtyDate);\n date.setSeconds(0, 0);\n return date;\n}","import { isHTMLSafe } from '@ember/template';\n\nexport default function(stringFunction) {\n return function([string]) {\n if (isHTMLSafe(string)) {\n string = string.string;\n }\n\n string = string || '';\n return stringFunction(string);\n };\n}\n","import { helper } from '@ember/component/helper';\nimport { htmlSafe as _htmlSafe } from '@ember/template';\nimport createStringHelperFunction from '../-private/create-string-helper';\n\nexport const htmlSafe = createStringHelperFunction(_htmlSafe);\nexport default helper(htmlSafe);\n","import { helper } from '@ember/component/helper';\nimport uppercaseLib from 'ember-cli-string-helpers/utils/uppercase';\nimport createStringHelperFunction from '../-private/create-string-helper';\n\nexport const uppercase = createStringHelperFunction(uppercaseLib);\nexport default helper(uppercase);\n","export default function uppercase(string = '') {\n if (typeof string !== 'string') {\n throw new TypeError(`Expected a string, got a ${typeof string}`);\n }\n\n return string.toUpperCase();\n}\n","import toInteger from \"../_lib/toInteger/index.js\";\nimport addMilliseconds from \"../addMilliseconds/index.js\";\nimport requiredArgs from \"../_lib/requiredArgs/index.js\";\n/**\n * @name addSeconds\n * @category Second Helpers\n * @summary Add the specified number of seconds to the given date.\n *\n * @description\n * Add the specified number of seconds to the given date.\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} amount - the amount of seconds to be added. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.\n * @returns {Date} the new date with the seconds added\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Add 30 seconds to 10 July 2014 12:45:00:\n * const result = addSeconds(new Date(2014, 6, 10, 12, 45, 0), 30)\n * //=> Thu Jul 10 2014 12:45:30\n */\n\nexport default function addSeconds(dirtyDate, dirtyAmount) {\n requiredArgs(2, arguments);\n var amount = toInteger(dirtyAmount);\n return addMilliseconds(dirtyDate, amount * 1000);\n}","import requiredArgs from \"../_lib/requiredArgs/index.js\";\nimport { secondsInMinute } from \"../constants/index.js\";\n/**\n * @name minutesToSeconds\n * @category Conversion Helpers\n * @summary Convert minutes to seconds.\n *\n * @description\n * Convert a number of minutes to a full number of seconds.\n *\n * @param { number } minutes - number of minutes to be converted\n *\n * @returns {number} the number of minutes converted in seconds\n * @throws {TypeError} 1 argument required\n *\n * @example\n * // Convert 2 minutes to seconds\n * const result = minutesToSeconds(2)\n * //=> 120\n */\n\nexport default function minutesToSeconds(minutes) {\n requiredArgs(1, arguments);\n return Math.floor(minutes * secondsInMinute);\n}","import toInteger from \"../_lib/toInteger/index.js\";\nimport addSeconds from \"../addSeconds/index.js\";\nimport requiredArgs from \"../_lib/requiredArgs/index.js\";\n/**\n * @name subSeconds\n * @category Second Helpers\n * @summary Subtract the specified number of seconds from the given date.\n *\n * @description\n * Subtract the specified number of seconds from the given date.\n *\n * @param {Date|Number} date - the date to be changed\n * @param {Number} amount - the amount of seconds to be subtracted. Positive decimals will be rounded using `Math.floor`, decimals less than zero will be rounded using `Math.ceil`.\n * @returns {Date} the new date with the seconds subtracted\n * @throws {TypeError} 2 arguments required\n *\n * @example\n * // Subtract 30 seconds from 10 July 2014 12:45:00:\n * const result = subSeconds(new Date(2014, 6, 10, 12, 45, 0), 30)\n * //=> Thu Jul 10 2014 12:44:30\n */\n\nexport default function subSeconds(dirtyDate, dirtyAmount) {\n requiredArgs(2, arguments);\n var amount = toInteger(dirtyAmount);\n return addSeconds(dirtyDate, -amount);\n}"],"names":["createTemplateFactory","scope","tc_","buttonSimple_","tc_0","on","DownloadApp","_dec","intlPath","path","_dec2","computed","_class2","Component","constructor","arguments","_initializerDefineProperty","_descriptor","_defineProperty","isMobileBrowser","showDownloadScreen","this","isMobileOrTablet","args","bypassDeviceCheck","redirectToApp","_this$navigation$getR","window","open","navigation","getRouteItem","AppDownload","url","_applyDecoratedDescriptor","prototype","service","configurable","enumerable","writable","initializer","Object","getOwnPropertyDescriptor","action","_class","setComponentTemplate","TEMPLATE","ExportType","ExportStatus","BaseVideoClipExportModal","_dec3","bool","_dec4","_dec5","_dec6","alias","_dec7","_dec8","owner","_id","_ref","_model$defaultCamera","super","_descriptor2","_descriptor3","_descriptor4","_descriptor5","_descriptor6","_descriptor7","_descriptor8","_descriptor9","_descriptor10","_descriptor11","_descriptor12","_descriptor13","_descriptor14","_descriptor15","_descriptor16","_descriptor17","_descriptor18","model","selectedCameraId","defaultCamera","cameras","id","duration","durations","getTranslation","key","intl","t","concat","getExportStatusTranslation","status","titleText","exportResource","isClipDownload","selectedExportOption","ExportOptionDirectDownload","triggerDownload","clipDownloader","downloadClip","clipExportType","requestDownloadUrls","handleDownload","downloadUrl","downloadFile","cancelExport","cancelTask","exportType","Download","DownloadAndUpload","includes","isDownloadTaskRunning","cancelClipExport","Upload","isUploadClipTaskRunning","clipUploader","showWarning","updateExportConfirmationModal","exportStatus","_this","fnGetButton","fn","isPrimary","length","undefined","getModalFooterButton","confirmButtonAction","taskIsRunning","preparingFileDownload","modals","closeModal","startDownloading","preparingUpload","startUpload","preparingDownloadAndUpload","startDownloadAndUpload","warningButtons","clipExportModalMessage","notificationManager","maxDate","downloadStartDate","selectedDateTime","defaultDate","sentryExtras","cameraId","sentryTags","feature","find","item","get","sentryErrorMessage","sentryWithScopeAndError","addError","fileRequestError","isEqual","isAfter","fileNotFound","uploadStartDate","uploadClip","uploadVideoClips","exportVideo","newDate","SDCard","assign","downloadInProgress","ExportOptionAddToSavedClips","SVR","uploadInProgress","ExportOptionDirectDownloadAddToSavedClips","isDownloadOrUploadTaskRunning","downloadAndUploadInProgress","tracked","formGroup_","t_","dropdownSelectSingleSelect_","ModalsVideoDownloadClipCameraSelector","availableCameras","_this$args$cameras","map","description","DropdownSelectItem","create","value","name","toString_","ModalsVideoDownloadClipDuration","getReadableDurationText","secondsToParse","Math","floor","NUM_SECONDS_IN_DAY","NUM_SECONDS_IN_HOUR","num","compact","join","durationItems","_this$args$durations","String","ExportOptionsComponent","availableOptions","_this$args$exportOpti","exportOptions","getReadableExportOptionText","updateValue","v","_this$args$updateValu","_this$args","call","Number","exportOption","modalsBaseFooterModalFooter_","VideoDownloadClipWarningModal","templateOnlyComponent","spinnerSvg_","UiPageBlockingLoadingOverlay","buttonIcon_","eq_","math_","t_0","UiSimplePagination","_buildTask","context","generator","timeout","restartable","toggleHover","isActive","autoHide","activeHover","sliderAdc_","ResultsToolbar","didInsert_","insetGroup_","dropdownActions_","simpleList_","simpleListItem_","chip_","dateRangePicker_","hash","popoverMenu_","checkboxTree_","svgSymbol_","not_","AppearanceSearchSidebar","resetOptions","appearanceFilterEnabled","enabledAppearanceSections","appearanceSections","allAttributeClassifiers","section","type","enabled","minimized","minimizedAppearanceSections","headerItems","SimpleListItem","icon","classifiers","classifier","title","options","option","isSelected","optionIsSelected","appearanceDropdownItems","_section$headerItems$","DropdownActionItem","toString","selectAppearanceSectionType","camerasDropdownItems","selectedCameras","subitems","camera","state","SELECTED","globalDeviceId","UNSELECTED","CheckboxTreeItem","isSelectable","showAllNoneSelectors","camerasSelectedText","_args$cameras","searchIsEnabled","selectedOptions","getDefaultStartDate","Date","now","NUM_MILLISECONDS_IN_DAY","attributeType","classifierType","optionType","some","o","changeSelectedCameras","newItems","filteredSelected","filter","changeSelectedDateRange","startEndDate","selectedStartDate","startDate","selectedEndDate","endDate","disableAppearanceFilter","goToAppearanceSearchResults","transitionToRouteId","EmberVideoAppearanceSearchResults","queryParams","JSON","stringify","toISOString","initialize","attributesResponse","ajax","apiRequest","convertGettAttributesResponseToAllAttributeClassifiers","appearancePopoverIsOpen","toggleOption","toggleSectionMinimized","appearanceGroupElement","document","querySelector","focus","allClassifiers","i","getAttributeTypeEnumName","getAttributeTypeEnumIcon","j","classifierInfo","newClassifier","getClassifierTypeEnumName","ClassifierTypeEnum","Mask","push","tc","Glasses","glasses","getGlassesEnumName","VehicleType","vehicles","getVehicleTypeEnumName","OutfitTop","OutfitBottom","VehicleColor","colors","getColorEnumName","attributeTypeString","AttributeTypeEnum","Person","Vehicle","string","colorString","ColorEnum","Black","Blue","Brown","Gray","Green","Gold","Orange","Red","White","Yellow","glassesString","GlassesEnum","NoGlasses","Sunglasses","vehicleString","VehicleTypeEnum","Bus","Car","Pickup","Suv","Truck","Van","getTimeRange","items","useDateTime","contextManager","lastObject","firstObject","formatDateTz","format","timeZone","showPreferredTimezone","identityModel","preferredTimezone","playMediaItems","mediaItem","media","rejectBy","showModal","VideoClipsModal","selectedIndex","indexOf","operatorSiteEnum","NotOperatorSite","BaseClipDisplay","sortBy","reverse","displayDate","isToday","timestamp","weekday","month","day","year","dayTimeRange","playMediaItem","BasePlayableClipComponent","downloadApp_","routeView_","promiseHashTracked_","didUpdate_","inlineAlert_","videoVideoStreamingVideoStreamingToolbar_","didResize_","videoVideoStreamingVideoStreamingPlayers_","await_","uiSimplePagination_","getCurrentlyStreamingPlayers","_this$activeCameras","currentlyStreamingPlayers","activeCameras","filterBy","forEach","getDeviceIdFromGlobalId","usageProtocolMapping","playerType","LiveVideo","equal","VideoStreamingFeatures","StreamUsage","LiveView","isAny","keys","POST","componentType","VideoStreamingFeaturesType","Live","afterCameraItemsProcessing","_this$playbackStateCo","playbackStateControllers","controller","resetPlayers","set","cameraGroupItems","_this$cameraGroups","cameraGroups","cameraGroup","cameraGroupId","showTimeoutMessage","isOperatorSite","systemHasRecentOperatorEvent","useStreamingToolbar","initialSetupDone","noSupportedCameras","setActiveCameras","newActiveCameras","changePage","newPage","stats","logEvent","PageChange","layoutControl","setExpandedCameraIndex","transitionToManagePage","manageGroupsRouteId","transitionToAddVideoDevice","VideoAddNewDevice","dataLoaded","cannotDoBrowserUploadsForOperatorSite","videoStreamingPermissions","locationCameraGroupInfos","onvifPtzPresets","sortedCameraGroups","liveViewCamerasCount","isCommercial","isEnterprise","setInitialSetupDone","isEscalatedEvents","hasTwoWayTalkdownInOperatorPortalPermissions","navigator","mediaDevices","getUserMedia","audio","video","excludedFromEscalatedEvents","excludedFromVisualVerification","addWarning","envSettings","isTestEnvironment","updateOperatorViewingSessionData","perform","addLocationGroupsToCameraGroups","makeSureLayoutIsSetCorrectly","maxVideosPerPageAutoView","canEditCameraGroups","canViewManageCameraGroups","centralStationLiveViewDuration","updateCameraGroupAndCamera","onvifPtzPresetManager","setPresets","onPlayStarted","setCameraIsPlayingProperty","onPlayEnded","onTimeout","setCameraProperties","hasStreamTimedOut","cameraItems","timedOutCameras","cameraItem","_cameraItem$model","sendAction","_len","Array","_key","actions","videoVideoPlayerOverlay_","coalesce_","noop_","videoVideoPlayerOverlayGeneralOverlayFeatures_","VideoLiveOverlay","or","BaseVideoLiveOverlay","enabledButtons","canViewSettings","didOperatorViewWithinADay","operatorAudioNotAvailableButtonContents","hasLiveViewBuzzDoorAccess","isOeStream","hasDetailedOsdOption","buttons","ButtonMoreOptions","inCriticalDataMode","ButtonPanTilt","ButtonDeterrent","ButtonLight","ButtonDetailedOsd","displayButton","ButtonOperatorAudioNotAvailable","ButtonRequestRecordingAndSnapshot","hasAssociatedDevices","ButtonAssociatedDeviceActions","ButtonOperatorLastViewed","ButtonSettings","canManagePresets","isPresent","VideoPanTiltSettings","showBottomBar","canPanTilt","requestRecording","buttonAnimation","isOnvifCamera","lastOnvifRequestRecordingCallTime","displayCameraButtonsPopover","then","isDestroyed","Promise","reject","promise","addSuccess","catch","error","errors","detail","later","saveSnapshot","async","resolve","fnThrowError","snapshot","belongsTo","reload","todayToString","downloadCrossOriginImage","cameraName","currentDate","replace","ex","onWarningSoundAction","areButtonsInPopover","isWarningSoundOn","toggleMoreOptions","toggleWarningSound","onLightAction","onOperatorLastViewedAction","toggleOperatorLastViewedPopover","panTilt","direction","zoom","buttonAsync_","WarningSoundPopover","popoverContent","infoResourceKey","buttonResourceKey","isError","button","message","htmlSafe","iconsCirclesDeviceStatus_","lockingResource","unlockingResource","AssociatedDevicesActionPopover","associatedDevices","updateDisplayDeviceList","updateDisplayActionList","drop","loadAssociatedDevices","handleClickAssociatedDevice","index","selectedDeviceIndex","displayActionList","displayDeviceList","numPrimaryDevices","primaryDevice","isDisplayedPrimaryDevice","device","selectedDevice","devicesWithStatus","displayMoreDevicesButton","isActionDisabled","getState","Unknown","deviceStatusArray","deviceStatus","deviceActionList","deviceActionStatus","actionList","changeSelectedDeviceState","selectedActionIndex","deviceType","managedDeviceType","stateInfo","inTransition","AccessControlDoor","newState","Closed","desiredState","Open","executeStateChange","Lock","Locked","Unlocked","stateText","Buzz","stateString","text","iconState","color","or_","videoVideoPlayerOespOsd_","liveVideoPlayer_","videoVideoPlayerOverlayLiveOverlay_","videoVideoPlayerOverlayWarningSoundPopover_","videoVideoPlayerOverlayAssociatedDevicesActionPopover_","videoVideoPlayerOverlayOverlayBorder_","MoreOptionsButtonClass","OperatorAudioNotAvailableButtonClass","OespTwoWayAudioTimeoutMs","DefaultHalfDuplexReenableAudioTimeoutMs","getPopoverId","buttonClass","playerIdHtml","requestWarningSound","warningSound","cameraSiren","warningSoundPromise","warningSoundResolver","start","Error","requestStopWarningSound","isForTwoWayAudio","stop","showWarningSoundDisabledDialog","goToSettings","infoText","showInfoModal","svg","info","css","store","transitionToSettings","VideoMainSettings","LiveViewPlayer","not","_dec9","and","_dec10","_dec11","_dec12","_dec13","_dec14","_dec15","_dec16","_dec17","_dec18","_dec19","_dec20","_dec21","_dec22","_dec23","task","BaseLivePlayer","_descriptor19","_descriptor20","_descriptor21","_descriptor22","_descriptor23","_descriptor24","_descriptor25","_descriptor26","_descriptor27","_descriptor28","_descriptor29","_descriptor30","VideoCameraSettingsOverview","videoPreloaderDetail","currentStreamIsEndToEnd","videoPreloader","getVideoPreloaderDetail","getPlayerId","BaseVideoIdPrefix","enableDigitalZoomPanForCamera","canZoom","isAudioActive","usesOesp","thirdPartyCameraAudioCapabilities","None","isProxyAndHasAudioSupport","supportsVolume","HasMicrophone","HasSpeakerAndMic","supportsMicrophone","HasSpeaker","shouldShowMicrophoneConnectionSpinner","playbackStateController","audioRecordingState","AudioRecordingState","Connecting","initiatedAudioRecordingStateChangeWithMicrophone","warningSoundButtonSelector","warningSoundButtonAnchorButton","associatedDevicesActionSelector","associatedDevicesActionAnchorButton","operatorLastViewedButtonSelector","operatorLastViewedAnchorButton","operatorLastViewedTimeDifferenceMS","lastOperatorViewedTime","abs","getTime","getTimezoneOffset","NUM_MILLISECONDS_IN_MINUTE","timeDifference","operatorLastViewedPopoverText","hoursDifference","NUM_MILLISECONDS_IN_HOUR","minutesModHoursDifference","hours","minutes","isPlayingOrFrozen","clickOperatorAudioNotAvailable","cameraRetriedInOperatorSite","cameraSupportsAudioOverProxy","cameraSupportsAudioOverEndToEnd","cameraSupportsOespAudio","cameraSupportsAudio","cameraIsntUsingAudio","oespCameraSupportsSomeAudio","cameraIsntUsingTwoWayAudio","buttonText","streamRetryable","buttonAction","onPoorStartingConnection","onCameraHasPoorStartingConnection","updateWarningSoundDisplayTask","warningSoundInfo","end","timestampEndUtc","differenceInMilliseconds","setOespProperties","next","setProperties","hasStreamConnected","playerCount","temporarilyDisableTwoWayAudioIfNeeded","selectedOespMasterPaneCameraId","disableTwoWayAudio","sendParentResumeMethod","sendResumeMethod","retryConnection","selectCameraWithLargeHybridCamera","onSwapHybridLargeView","selectPreset","presetId","goToPreset","currentPreset","displayPanTiltPopover","physicalPtzPosition","panTiltX","panTiltY","zoomLevel","CENTER_PTZ_PRESET","CENTER_PRESET_ZOOM_AMOUNT","updatePtzPosition","ptzPosition","arePanTiltValues","connectMicrophoneForAllCamerasOnSvr","apexConnectionInfo","apexId","svrIdRefreshedFromMicrophoneConnection","didTwoWayAudioConnectionRefresh","connectUsersMicrophoneAudio","isMicrophoneConnected","svrIdsWithMicrophoneConnectionInProgress","setMicrophoneConnectionInProgressForSvr","has","audioPromise","stream","getTracks","track","shouldResetEndToEndStreamFailed","cookieManager","setEssentialCookie","MICROPHONE_ACCESS_COOKIE_NAME","setSvrIdRefreshedFromMicrophoneConnection","oeAudioInfo","svrIdWithAudio","changeCameraAudio","setSelectedOespMasterPaneCameraId","setOEAudioInfo","stopAudioRecording","initializeVideoSource","hasBlockedMicrophoneAccess","addDays","shouldMute","volume","isEnabledAutomaticallyAfterDelay","cameraWasAutoMuted","oeSVRShouldMuteAudio","webrtcStateController","isAudioFullDuplex","isOespCameraMuted","setForceHideIdleAudioIcon","toggleMuteMicrophone","playerIdWithAudio","toggleMicrophoneMute","forceShowOverlayForMicrophone","stopWarningSound","isWarningReactionEnabled","forceShowOverlayForWarningSound","activateWarningSound","closeWarningSoundPopover","warningSoundError","showAssociatedDevicesActions","displayAssociatedDevicesActionPopover","closeAssociatedDevicesActionPopover","toggleOperatorLastViewed","forceShowOverlayForOperatorLastViewed","operatorAudioNotAvailableButtonSelector","displayOperatorAudioNotAvailablePopover","restartStreamViaOperatorAudioNotAvailablePopover","OperatorAudioNotAvailableButtonRefreshedStream","retryEndToEndWithAudioRequest","closeOperatorLastViewedPopover","onSirenChange","_this$warningSoundRes","Invalid","_this$warningSoundRes2","cancelAll","DATETIME_FORMAT","setOsdSize","playerSize","getPlayerSize","playerDimensions","sizeStyleClass","getSizeStyleClassFromPlayerSize","formatTime","renderTime","date","toDate","utcToZonedTime","OespOsd","htmlSafeSizeStyleClass","formattedVideoCodec","_this$args$osdPropert","streamStats","osdProperties","videoCodec","cachedFormattedVideoCodec","formatVideoCodec","formattedOsdProperties","timeDisplay","resolutionDisplay","formatResolution","codecDisplay","bitRateDisplay","formatBitRate","frameRateDisplay","formatFrameRate","updateOsdSize","once","DISCONNECTED_STATE","BaseOverlay","timeoutMs","logPlayerError","errorEnum","canStreamVideo","NoPermissions","StreamNotAvailable","reportStreamingErrorToWaveFront","logFinalPlayerError","NoError","isDisconnected","IcnView360Full","IcnView360HalfPano","IcnView360Interactive","IcnView360TwoPano","ptzButtons_","DewarpingSelectorPanel","mode","FisheyeMode","Original","label","component","IcnViewThreesixtyFull","Panorama","IcnViewThreesixtyHalfPano","SplitPanorama","IcnViewThreesixtyTwoPano","Ptz","IcnViewThreesixtyInteractive","isVideoVisible","PLAYING_STATE","READY_STATE","playerState","isInInteractiveMode","fisheyeMode","fisheyeModes","interactiveModeActions","dewarpConfig","validateParams","syncDewarpConfig","createAction","panUp","adjustFisheyePanTiltForApexId","panDown","panLeft","panRight","zoomIn","adjustFisheyeZoomForApexId","zoomOut","resetZoom","resetFisheyePanTiltZoomForApexId","interactiveModeDisabledButtons","isDisabled","down","left","reset","right","up","setFisheyeMode","_this$args$togglePanT","lastPan","lastTilt","lastFov","setFisheyePanTiltZoomForApexId","togglePanTiltOptions","modalsDialogModalsSimpleSimpleDialog_","array","getModalButton_","emberDragula_","emberDragulaContainer_","and_","cached","esc","require","EditOnvifPtzPresets","preset","presetToBeDeleted","presets","_this$_localPresets","_localPresets","dragulaConfig","copy","moves","_el","_source","handle","deletePresetTask","isRunning","classList","contains","enabledEvents","presetNumbers","from","_","emptyPresets","amount","setDragIndex","el","source","children","child","hasAttribute","dragIndex","syncPresets","parent","parentElement","reorderPresets","fixDOM","element","elementForId","Map","remove","dataset","appendChild","initialIndex","newIndex","splice","deletePreset","e","console","log","savePresets","textInput_","NewOnvifPtzPreset","OnvifPtzPanel","presetIndex","sortedPresets","ptzController","getPtzControllerForApexId","gotoPreset","presetNumber","_this$onvifPtzPresetM","presetsByCameraId","sort","a","b","position","_reorderedPresets","selectedPreset","_preset","selectPresetByIndex","openNewPresetModal","openEditPresetsModal","videoVideoPlayerOverlayDewarpingSelectorPanel_","videoVideoPlayerOverlayOnvifPtzPanel_","PtzPopoverMenu","videoVideoPlayerOverlayTwoWayAudioButtons_","videoVideoPlayerOverlayPlayerButtons_","videoVideoPlayerOverlayPtzPopoverMenu_","GeneralOverlayFeatures","displayCameraButtonsPopoverAnchorSelector","showGeneralOverlayFeatures","makeOverlayVisible","popoverIsOpen","systemDescription","showIdleAudioIcon","oeShouldMuteAudioInfo","forceHideIdleAudioIcon","shouldMutePlayer","showThumbnailSearch","thumbnailSearchPage","getContextAwareThumbnailSearchPage","identityManager","supportsThumbnailSearch","userHasAccess","relativeDirections","getRelativeDirections","disabledPTZButtons","panTiltButtonsArePhysical","zoomButtonsArePhysical","zoomPanLimitations","disabledButtons","zoomedInEnoughToPanTilt","minZoomLevelForPanTilt","canPanLeft","canPanRight","canPanUp","canPanDown","FULL_PTZ_PRESET","maxZoomLevel","canZoomIn","canZoomOut","standardPtzActions","bind","in","out","thumbnailSearchName","_this$navigation$getR2","pageTitle","canZoomPtzOut","_this$disabledPTZButt","isMicrophoneAudioInError","_this$args$playbackSt","isUsingOespPhysicalPtz","isLiveVideo","hasPtzEnabled","has3PCPanTilt","has3PCZoom","oespPtzActions","handleOespPtz","panTiltZoom","tilt","pan","gotoHome","oespPtzDisabledButtons","goToAdjacentVideo","isForward","_this$args$goToAdjace","managePanTiltPresets","transitionToSettingsRoute","_this$args$digitalZoo","_this$args3","_this$args$updatePtzP","_this$args2","panTiltAmounts","sentryWithScopeAndWarn","x","y","digitalZoomPan","_this$args$digitalZoo2","_this$args7","_this$args$updatePtzP2","_this$args6","_this$args$selectPres","_this$args4","_this$args$selectPres2","_this$args5","zoomAmount","onBottomBarIconsResize","availableButtonSpace","clientWidth","onBottomBarUpdate","_this$args$toggleDown","_this$args8","downloadPopoverIsOpen","isElementViewable","downloadPopoverAnchorSelector","toggleDownloadPopover","_this$args$toggleMore","_this$args9","panTiltPopoverAnchorSelector","_this$args10","onThumbnailSearchClick","_this$args$goToThumbn","_this$args11","goToThumbnailSearch","ButtonPixelsWide","OverlayBorder","headerClickAction","_this$args$headerClic","toolTip_","MouseAction","KeyAction","addMouseUpTouchEndDomListener","usingMicrophoneButton","actionType","dom","holdEndEventType","holdEndEventId","addListener","handleAudioMicrophoneToggleForHalfDuplex","isMouseDownOnVolumeSlider","removeListener","handleChangeCameraAudio","hasEnabledSoundFirstTime","isSoundEnabled","volumeSliderValue","setUnmutedSliderVolume","unmutedSliderVolume","enableDisableCameraAudio","_oeShouldMuteAudioInf","_oeShouldMuteAudioInf2","_this$args$changeCame","showAnimation","camerasSVRWasMuted","shouldMuteSVR","animateSoundButton","enableDisableMicrophoneAudio","_oeShouldMuteAudioInf3","_oeShouldMuteAudioInf4","_this$args$toggleMute","hasLoggedTalkdownEvent","isMicrophoneEnabled","handleAudioMuteToggleForFullDuplex","handleAudioMicrophoneToggleForFullDuplex","isDown","enableCameraAudioAfterPause","processKeyPresses","event","isKeyDown","target","isSelectedForKeyboardPress","nodeHandlesKeyboardInput","connectMicrophone","toggleCameraAudioMute","TAB_CODE","_document$activeEleme","_document$activeEleme2","isSoundButtonNoticeable","activeElement","muteUnmuteCameraAudio","TwoWayAudioButtons","LOADING_STATE","FROZEN_STATE","INITIALIZING_STATE","audioDelayParam","URLSearchParams","location","search","parseInt","_this$args$enableCame","enableCameraAudioAfterPauseStarted","_this$args$setForceSh","_this$args$setForceSh2","setForceShowOverlayForVolumeSlider","microphoneButtonId","guidFor","displayVolumeButton","isPlaying","isFrozenOrReady","displayMicrophoneButton","isFrozen","disableMicrophoneButtonTemporarilyOnDepress","soundButtonSvg","soundButtonText","microphoneButtonSvg","displayAudioIssueOccurredMessage","microphoneButtonText","textId","isSliderVertical","PlayerSize","XXSmall","XSmall","Small","showCameraSpeakerAlreadyInUseMessage","_this$identityManager","cameraSpeakerAlreadyInUse","setIsMouseDownOnVolumeSlider","isMouseAction","handleTasksUponMicrophoneConnection","isPlayingAndIsMicrophoneConnectedAfterPlayerRefresh","hasHandledTasksUponMicrophoneConnection","setCameraAudioVolume","shouldMuteAfterPlayResume","handleAudioStateOnPlayerStateChange","isLoading","hasStreamLoadTriggered","isInitializing","userHasNotEnabledSound","isCurrentlyMuted","isFirstTimePlaying","isResumingAndShouldMute","handleHalfDuplexMicrophonePressStart","preventDefault","_this$args$connectUse","microphonePromise","displayMicrophoneBlockedMessage","clickFullDuplexMicrophoneButton","onOeShouldMuteAudioUpdate","_this$args$oeShouldMu","_this$args$oeShouldMu2","handleMicrophoneButtonHover","isHovering","addHotKeys","hasInternalBetaAccess","preventBubblingKeyboardEvents","stopPropagation","modalsDateDatePicker_","DateTimePickerModal","IntervalSetting","NextAvailableTimeAction","FnRecordToDate","record","IntervalsControl","gt","EmberObject","playbackInfoCacheManager","_playbackInfoCacheManager","allStreamsIntervals","_allStreamsIntervals","earliestPlaybackTimeUtc","_earliestPlaybackTimeUtc","earliestRecord","_earliestRecord","latestRecord","_latestRecord","setPlayerType","_playerType","getEarliestAndLatestRecordDates","allStreamsEarliestRecordDate","allStreamsLatestRecordDate","streamEarliestRecordDate","streamLatestRecordDate","earliestRecordDate","latestRecordDate","getIntervalDataForTimeWindow","intervalsFound","timelineStartTime","timelineEndTime","intervals","startTime","endTime","toggledBy","getIntervals","forceLoadFreshIntervals","getVideoSource","allIntervals","all","vidSource","getIntervalsFromSource","getStreamIntervalsArrayForTimeWindow","activelyRecording","intervalsData","getCameraItemByGlobalDeviceId","getStreamPausedStatus","_this$_allStreamsInte","_stream$cameraItem","_recordingSchedule$is","_this$_allStreamsInte2","cameraModel","videoSource","recordingSchedule","isPaused","intervalsToAllStreamsIntervals","getProperties","toArray","nextVideoAvailableForStream","intervalData","_intervalData$interva","nextVideoAvailableAt","interval","_ref2","intervalEnd","intervalStart","setAllStreamsIntervalsFiltered","newAllStreamsIntervals","_intervalsData$interv","_objectSpread","_ref3","Continuous","_allStreamsIntervalsFiltered","determineNextAvailableTimeAction","time","isAvsContext","initStarted","seekTypeEnum","intervalsControlData","intervalInfoAtTime","getDataForTime","_intervalsControlData","isInGap","nextAvailableTimeAction","DisconnectNoPlayback","HandleNewTime","UpdateCurrentTime","_intervalData$interva2","any","ResetIntervalsAndResume","DisconnectPlaybackEnded","getData","getIntervalInfoForCurrentTime","getAndStoreEarliestAvailablePlaybackTime","_ref4","firstInterval","reduce","earliestDate","isBefore","currentTime","streamsInfo","streamsInGapCount","nextVideoTime","_intervalsData$camera","streamNextVideoTime","getIntervalsFromCacheIfNeeded","resetIntervalsSetting","deviceIds","initialStreamDataLoaded","Normal","HardReset","getVideoSourceFromCache","getIntervalsFromCache","allStreamsIntervalsIndividual","addVideoSourceToCache","addIntervalsToCache","getIntervalUsabilityAndUpdateValues","avsDataObject","foundUsableIntervalData","foundPlayerWithoutErrors","errorEnumMapping","_intervalsData$errorE","searchFailed","allStreamsIntervalsForWindow","getResetTimeValues","timeInterval","newCurrentTime","subSeconds","addSeconds","intervalsDataMatchesDisplayedCams","cachedCameraItemParameters","isEmptyObject","displayedDeviceIds","every","deviceId","loadSvrMotionIntervals","newIntervalMap","_cameraItem$player","svrVideoSource","svr","player","supportsMotionIntervals","motionIntervals","getSVRMotionIntervals","newIntervals","Motion","data","motionInterval","attributes","newMotionInterval","_intervalsData$camera2","intervalsForDevice","nextVideoForStream","setEarliestAndLatestRecords","getCamerasCountInState","getCamerasInState","PlaybackControl","timezone","setPlayerUrls","moveToNextAvailableStartTime","getPlaybackStateControllers","_timezone","_isTestEnvironment","_setPlayerUrls","_moveToNextAvailableStartTime","_stats","_ajax","_getPlaybackStateControllers","_playersControl","PlayersControl","setAutoPlayWhenReady","_autoPlayWhenReady","_isPlaying","_currentTime","hasSeekedAfterPause","_hasSeekedAfterPause","initialSeekForPlaySeconds","_initialSeekForPlaySeconds","_initStarted","isTimelineButtonDisplayingPlayIcon","_isTimelineButtonDisplayingPlayIcon","pageState","_pageState","_seekTypeEnum","setSeekTypeEnum","speed","_speed","speedIndex","_speedIndex","_timeInterval","setTimeInterval","_timelineStartTime","_timelineEndTime","scrubberTime","usingHourMode","allCamerasDisconnected","calculatePageState","states","_statePriority$find","NOT_VISIBLE_STATE","priority","convertCurrentStateEnumToString","currentStateEnum","deletePlayersControlCommands","cameraIndex","deletePlayerCommands","disconnectNoPlaybackAvailable","camerasDataObject","hasReachedEndOfStream","ALL_CONNECTED_CAMERAS_ID","handleDisconnectedPlaybackPlayer","NoPlaybackVideoAvailable","disconnectPlaybackEnded","PlaybackEnded","getTimelineChangeFromCurrentTimeChange","oldCurrentTime","timeChange","differenceInSeconds","datePercentage","saveCursorPosition","moveTimelineForward","newStartTime","round","streamConnectionErrorEnum","camerasModel","updatePageAndPlayerState","resetPlaybackButtons","handleOnPlayStarted","_loadStartTime","_playbackRestarted","_isPaused","reportPlaybackLoadingTimeToWaveFront","performance","handlePlaybackPrepared","useHdStream","intervalsControlDataForCurrentTime","startVideoPlayback","handleSeekOrSpeedChangeAfterPause","_hasSetSpeedAfterPause","setSpeed","seek","incrementTimer","newStreamsInGapCount","currentStreamsInGapCount","_streamsInGapCount","seekToCurrentTime","updateIsInGapStatus","newTime","startTimer","onSpeedChange","newSpeed","availableSpeeds","isNaN","getSpeedDropdownEventEnum","setSpeedValues","SpeedDropdown","WebRtcProxyPlaybackStateController","setPlayerUrlsForAllCameraItems","pause","Pause","stopTimer","refreshVideoSource","setPlayerUrlsForCameraItem","loadStartTime","loadEndTime","playbackRestarted","playbackSpeed","loadTimeInMilliseconds","useWebRtc","ALL_CAMERAS_ID","resumePlayback","isUserResumeAction","Play","resume","deviceIdsDisplayingOnPage","resetIntervalsAndStartPlayback","Retry","AutoRetryConnection","addPlaybackTimesToCache","defer","_seekInterval","cancel","setLoadStartTimeAndPlaybackRestartedForWavefrontLogging","updateUrl","playing","addMinutes","_error$errorEnum","PlaybackServerConnectionFailed","OespPlaybackStateController","setupPlayers","startOespLiveRelay","newSpeedIndex","setTimelineBoundsToMidnight","localCurrentTime","startOfLocalCurrentDay","startOfDay","endOfLocalCurrentDay","zonedTimeToUtc","delay","max","NUM_MILLISECONDS_IN_SECOND","_tickInterval","setTimelineTimes","isRestart","connectionStartTimeForStreamLogging","connectionStartTime","_error$errorEnum2","implementsBasePlayer","startPlayback","updateCurrentTime","updateTimelineAndLoadThumbnailsAndEvents","newTimelineStartTime","updateHasSeekedAfterPause","isNotInGapCallback","streamInfo","loadingPercentage","playerStates","newStateString","oldStateString","errorString","convertErrorEnumToString","updatePageControls","updatePlayersControlCommands","commandFunctions","updateCommands","updateTimeline","newEndTime","updateToFrozenStateIfValid","formatTimeTz_","EventHistoryItem","eventItem","isVideoEvent","eventType","VideoCameraTriggered","VideoEventTriggered","ovMapping","Human","classificationIconLookup","Animal","ovClassification","iconData","click","HTMLElement","blur","onEventClick","uiBlueDot_","dropdownSelectMultiSelect_","videoEventHistoryItem_","arrayIncludes_","createDropDownItem","isOvItem","setDefaultOrCookieSelections","ignoreCookies","deviceIdFiltersDropdownItems","defaultSelectedDeviceIds","deviceTypesFiltersDropdownItems","historyEventFiltersDropdownItems","deviceTypesCookie","historyEventsCookie","_this$contextManager$","routeName","currentRouteData","deviceTypesCookieJson","getCookieForPage","COOKIE_DEVICE_TYPES","historyEventsCookieJson","COOKIE_HISTORY_EVENTS","parse","hasSubitems","foundCookieForItem","cookieValue","val","dropdownsSelectedAreDefault","selectedDevices","storeFiltersToCookie","dropdownMap","storeCookieForPage","VideoEventHistory","eventsDisplay","currentFilter","events","filteredEvents","sortedEvents","groupedEvents","formatDate","eventDate","eventsToShow","hasVideoAnalyticsReadAccess","historyEventFilters","eventTypeFilterItems","accumulated","filterIcon","pushObjects","UserSelected","deviceTypes","filters","f","isEmpty","devices","isCameraDevice","mapBy","applyFilters","selectedEventTypes","clipsWithOvClassification","split","uniq","selectedDeviceTypes","showFilter","filterApplied","filterFn","eventId","deviceTypeFilterIds","videoClips","clipHasOvClassification","dev","loadEventHistory","updateUsingDefaultFilterStatus","clearFilter","onCameraItemsChanged","initialFilterApplied","onFilterItemsChanged","ResultsStatusBar","addKeyDownListeners","navigateToSvrTimeline","goBackToAvsSearch","_this$args$currentTim","svrTimelinePage","getContextAwareSvrTimelinePage","goBackToSearchAndPauseVideo","pauseVideo","ResultImageSize","findNextMatchingResultIndex","moveForwards","searchResults","indexToStartFrom","resultsLength","indexToCheck","goToThisResult","FoundSearchResults","searchFailedOrInterrupted","searchWasInterrupted","errorText","scrollAbility","canScrollRight","listScrollAmount","maxScrollDistance","canScrollLeft","scrollPositionStyle","displayedSearchResults","_this$args$searchResu","idx","thumbnailUrls","timeRange","imageSource","getFullUrlForScrubberThumbnail","timeString","hour","minute","rangeString","seconds","componentWidth","resultImagesLength","fullyVisibleImageResultRange","firstIndex","ceil","lastIndex","getBoundedScrollPosition","scrollPosition","constrainRange","changeSelectedResultAndPlaybackTimeInNext","resultIndex","changeSelectedResultAndPlaybackTime","updateComponentSize","scrollList","amountOfResultImagesVisible","scrollAmount","newListScrollAmount","leftSideCutOffAmount","changeSelectedResult","searchResult","timelineNewTimeSet","TimelineClick","onKeyDownFromResult","isEnterCode","restartAvsSearch","onCurrentTimeUpdate","selectedResultIndex","svrTimelineIsHidden","closestResultIndex","selectedResult","nextMatchingResultIndex","setTimeout","isHidden","onVisibilityUpdate","onSelectedResultIndexUpdate","scrollPositionIfResultIndexIsCentered","newScrollPosition","guidFor_","appLoadingIndicator_","formatDateTz_","videoAdvancedVideoSearchFoundSearchResults_","DEFER_TIMEOUT_PERIOD_MS","MouseLocation","isTouchEvent","TouchEvent","updateSliderPercentage","percentage","isFromUserEvent","sliderPercentage","timelineUpdate","getTimeFromSliderPercentage","millisecondsInTimeline","addMilliseconds","getSliderPercentageFromTime","getLocalizedPercent","xOffset","isRtl","getRtlSideString","getSliderPercentageFromEvent","_document$getElementB","onlyInside","touches","clientX","body","scrollLeft","documentElement","pageX","sliderOffset","getElementById","getBoundingClientRect","width","min","processPressEvent","stopImmediatePropagation","areControlsEnabled","removeTimelineDomListeners","offset","timelineSelectionStart","moveListener","upListener","mouseMove","mouseUp","processHoverEvent","mouseMoveHover","isDragging","isMouseDown","mouseIn","expandedMode","debounce","loadScrubberThumbnail","mouseMoveHoverForStream","hoveredStreamIndex","getIntervalEdge","videoTime","intervalTime","isStartTime","fnResults","streamIndex","_orderedThumbnailUrlL","hideScrubberThumbnails","orderedThumbnailUrlList","currentThumbnailIndex","getCurrentThumbnailIndex","selectedScrubberThumbnail","hoveredImages","getElementsByClassName","image","imageUrl","src","complete","naturalWidth","displayScrubberThumbnail","thumbnailLoadListener","addEventListener","setAttribute","minuteIndex","display","hoveredImage","onload","removeEventListener","add","convertIntervalsArrayToIntervalsDisplayArray","intervalsGroup","videoMotionIntervalType","startPercent","sideString","widthPercent","typeString","Restricted","styleCss","createMarkerObject","leftPercent","eventIds","getIconForEvent","isCollation","getThumbnailImage","thumbnailUrl","thumbnailCache","thumbnailImage","Image","alt","className","updateTime","wavefrontAction","tooltipTime","thumbnailMinutesIncrement","startTimeRoundedByInterval","scrubberThumbnailsRequestTimeParameters","scrubberThumbnailUrl","formattedStartTimeUtc","TimeLineComponent","reads","_dec24","_dec25","_dec26","_dec27","_dec28","_dec29","tooltipLocation","selectedTime","streamTypeCss","numberOfStreams","scrubberThumbnailUrls","preloadScrubberThumbnails","_this$args$scrubberTh","individualThumbnailMode","eventToMarkerMapping","allHoveredMarkerEvents","marker","highlightedMarkerId","highlightedEventIds","currentlyHoveredMarkerEvents","mouseLocation","previousHoverEventInfo","markerEventsObject","findBy","markerEvents","areArraysSame","primaryMarkerSelector","secondaryMarkerSelector","anchorSelector","PrimaryMarker","filteredMarkerEvents","permanentEvents","permanentMarkersDisplay","hideFromPrimaryStream","matchingEvents","markerEventData","deviceDescription","correlatedEventId","thumbnail","individualStreams","expandedCameraIndex","_avsDataObject$search","_permanentMarkersDisp","isSchedulePaused","intervalArrayToConvert","intervalsDisplay","cameraDescription","selected","numIndividualStreams","_this$individualStrea","_this$individualStrea2","videoIntervals","restrictedIntervals","eventFilterFn","deviceTypeFilter","markers","markersToCollate","collationPointsData","currentMarker","previousMarker","collationPointData","newMarker","earliestMarker","lastMarker","createCollatedMarker","getMarkersCollated","noVideoAvailableStart","earliestTime","noVideoAvailableEnd","latestTime","hideHighlightedEventsIfNeeded","Other","eventHover","secondaryMarkerIdToHighlight","highlightedPopoverEventId","sliderThumbStyle","sliderTransitionTime","localizedPercent","transitionStyle","tooltipStyling","mouseInMarkerOrPopover","visibilityClass","iconClass","leftCss","daybreakStyle","startTimeInTimeZone","endTimeInTimeZone","midnightInTimeZone","setHours","markerPercent","markerPercentRtlSafe","scrubberThumbnailProperties","properties","_properties$minutesBe","_properties$minutesBe2","minutesBetweenThumbnails","DayMode","HourMode","SecondaryMarker","Popover","timelineStyle","showAvsThumbnails","height","thumbnailUrlList","orderedThumbnails","thumbnailList","thumbnails","cssClass","numThumbnailsRequired","NUM_SECONDS_IN_MINUTE","numMillisecondsInThumbnailMinutesIncrement","endTimeRoundedByInterval","getThumbnailUrlListTask","promises","_scrubberThumbnailUrl","formattedEndTimeUtc","prepUrl","request","toLowerCase","_unused","requestUrlTime","onPopoverInsert","eventInfo","timeline","overlapAmount","offsetWidth","marginLeft","DEFAULT_POPOVER_MARGIN_LEFT","eventInfoStyle","mouseClicked","which","touchStarted","back","logEventConditionToWavefront","TIMELINE_TIME_UPDATE","TimelineArrowBack","forward","TimelineArrowForward","getThumbnailUrlListDebounced","timelineChangeDebounceTimeMs","getThumbnailUrlList","popoverEventHover","handleMouseEnter","handleMouseLeave","showMarkerHover","fromPrimaryMarker","scrubberThumbnailHoverOut","onInsert","onPopoverConnectorMouseOut","popoverConnector","leavingConnectorFromSides","offsetX","onMarkerMouseOut","relatedTarget","scrubberThumbnailHoverIn","setInPopoverValue","inPop","setPausedToolTipIndex","pausedToolTipVisibleIndex","updateCurrentTimeSlider","isBetween","thumbnailUrlTaskInfo","restartableTask","exists_","videoEventHistory_","videoAppearanceSearchSearchSidebar_","videoAdvancedVideoSearchResultsStatusBar_","videoAppearanceSearchResultsToolbar_","videoVideoTimeline_","uiPageBlockingLoadingOverlay_","ThumbnailsDownloadDurations","deviceIdMatchesSelectedDevices","getPlayerByDeviceId","cameraGlobalDeviceId","PlaybackFeatures","ForcedStreamingMethodEnum","ForceWebRTCProxy","notEmpty","SeekBack","SeekForward","_newPageNumber","_newIndex","_callback","_descriptor31","hideSidebar","usingEventHistorySidebar","showErrorMessage","_this$playbackControl","snapshotEndpoint","snapshotTimestamp","playbackControl","intervalsControl","setWebStreamingLogType","init","initialTimeInterval","eventTypeFilters","changeTimeInterval","resetTimes","result","setSelectTimeWindowMethod","_newCurrentTime","Playback","getClipExportOptions","_deviceId","forcedStreamingMethod","shouldForceEndToEndWithExtendedTimeouts","ForceWebRTCEndToEnd","forcedStreamingMethodFromQueryParam","_this$cameras","appearanceSearchDataObject","formattedTimelineStartDate","formattedTimelineEndDate","disabled","isCoverageLoaded","resourceKeys","baseResourcePath","hasServicePlan","addSchedule","addDevice","expandCollapseTimelineButtonText","textKey","collapsedModeForTimeline","showHideSidebarButtonText","showCollapseSidebarControl","disablePlayPauseButton","_this$avsDataObject","speedOptions","singlePlayerDimensionsStyle","singlePlayerDimensions","_this$cameraItems","_player","_videoEndTime","loadMotionIntervals","getClipDownloadDurations","getClipUploadDurations","getClipDurations","clipDownloadDurations","clipUploadDurations","downloadAndUploadDurations","getThumbnailDurations","allPossibleClipDownloadDurations","allPossibleClipUploadDurations","shouldReload","videoSourceEndpoint","getCamera","existingVideoSource","videoSourceModelPath","findRecord","streamingProperties","reloadVideoSource","forceProxy","forceProxyFromQueryParam","getScrubberThumbnailUrl","existingEndpoint","scrubberThumbnailEndpoint","doSelectionChange","resetIntervals","setScrubberThumbnailProperties","setScrubberThumbnailUrlsDebounced","getLocalTranslation","_cameraItem$model2","playerId","resetPlayerStates","activeCamera","hardResetSource","successCallback","intervalsFromCacheInfo","cachedAllStreamsIntervals","getAndAddMissingIntervalsToAllStreamsIntervals","getPlaybackTimesFromCache","handleIntervalsLoadMotionPreparePlayback","loadingStreamInformation","handlePrepareResult","onSetIntervalsFailed","handleIntervals","isLoginRestrictedFromLiveVideo","lockTimelineBoundsToAvailableVideo","visualVerification","intervalUsabilityInfo","entries","newEarliestPlaybackTimeUtc","lastAlarmDate","playerTypeString","warn","savePlaybackTimesToCache","onAlarmChanged","onEventHover","onFilterApplied","keyDownHandlerForPlayback","onTimelineSelectionStart","onTimelineUpdate","shouldResumePlayback","resumeOrRetryIfNeeded","onTimelineNewTimeSet","timelineEnum","handleNewTimeSelection","storeCookieAndLogToWaveFront","isDayMode","COOKIE_INTERVAL","PLAYBACK_INTERVAL","onTimeIntervalChange","onSyncTimer","newOffset","adjustedStartTime","preparePlayback","toggleDatePicker","PLAYBACK_DATE_PICKER","modalIsOpen","coveredDays","Set","_stream$intervals","eachDayOfInterval","minDate","disableDate","onSelection","toggleCollapsedModeForTimeline","PLAYBACK_EXPAND_COLLAPSE_TIMELINE","COOKIE_USE_COLLAPSED_TIMELINE","toggleHideSidebar","closedFromSidebar","isEventHistory","sidebarToggleHasBeenUsed","sidebarButtonIsFlashing","PLAYBACK_SIDEBAR_OPEN_CLOSE","COOKIE_HIDE_SIDEBAR","switchSidebarTask","onError","_playerId","_errorInfo","isTimeout","isEndOfStream","_activeCameras$findBy","intervalInfo","streamError","PlaybackStreamConnectionFailed","StreamDisconnected","PlaybackStreamTimeout","StunReconnectionFailed","seekEnum","PLAYBACK_SEEK","fromTime","AutoSkipGap","resetTimeValues","toggleHD","send","timelineStartTimeChanged","loadEventHistoryAndMotionIntervals","goToEvent","isFromTimeline","_event$thumbnailTimes","TIMELINE_EVENT_POPOVER","thumbnailTimestamp","ActivityEvent","shouldResume","seekEvenIfPaused","query","PlaybackPagesEventHistoryItems","includeCommands","getThumbnails","onSwapCamera","openExportClipModal","DOWNLOAD_CLIP","openExportModal","clipDownloadModalComponent","openDownloadThumbnailsModal","thumbnailsDownloadModalComponent","setLoadingPercentage","savePlaybackSnapshotTask","updatePage","goToAddNewVideoDevice","groupResolution","autoViewMaxVideosPerPageLimit","hasAttributeSearch","Highest","goToAdjacentAvsVideo","changeSelectedAvsResult","goToAvsSearch","advancedVideoSearchRoute","EmberEnterpriseVideoAdvancedVideoSearch","EmberVideoAdvancedVideoSearch","isSdCardComponent","isSdCard","insertedViewWrapper","focusOnAppContent","onSidebarResize","updatePlayersDimensions","autoViewLayoutOptions","showPagination","onUsingDefaultFilterStatusChange","usingDefaultFilter","resizeVideoPlayers","activities","players","dynamicVideoPlayerDimensions","clientHeight","Log","selectedDate","DateTimePicker","updateShouldForceEndToEndWithExtendedTimeouts","newShouldForce","oldAllStreamsIntervals","missingDeviceIds","missingAllStreamsIntervals","missingCameraItems","keyCode","shiftKey","eventFiredWithModifier","D_KEY","modalsToRender","EQUALS_KEY","SPACE_KEY","nodeHandlesSpaceOrEnterInput","LEFT_ARROW_KEY","RIGHT_ARROW_KEY","LEFT_BRACKET_KEY","RIGHT_BRACKET_KEY","modalComponentPath","clipExportOptions","forceShowOverlayForExport","disableCameraSelection","_cameraItem$model3","_cameraItem$model4","_cameraItem$model5","streamUsageToScrubberThumbnailsMapping","aspectRatio","forcedAspectRatio","setScrubberThumbnailUrls","_cameraItem$model6","_eventId","_deviceTypeFilterIds","_ovClassification","_globalDeviceId","modalsLoadingLoadingSpinner_","modalsVideoDownloadClipWarning_","modalsVideoDownloadClipCameraSelector_","modalsVideoDownloadClipDuration_","simpleBinary_","handleBinaryChange_","modalsVideoDownloadClipExportOptions_","safeHtml_","SvrClipDownloadModal","ClipDownloadModal","fetchStreamSettings","streamSettings","streamResolutionGreaterThanEightMegapixels","setting","streamId","HighStreamId","convertResolutionToPixelCount","resolution","_this$selectedCamera","selectedCamera","_this$selectedDateTim","getSvrClipDownloadUrl","isDownscaledVideo","includeAudio","shouldAppendAdditionalTimestamp","isArmSvrWithStreamGreaterThanEightMegapixels","_this$selectedCamera2","apexSvrCpuArchitecture","ARM","shouldDisableAdditionalTimestampsCheckbox","appendAdditionalTimestampMessage","vlcMessageResource","isWindowsDevice","vlcLink","_this$selectedDateTim2","uploadSvrVideoClip","handleDurationChange","updateDuration","newExportOption","getOespControllerAndChannelGuid","apexConnectionRelationship","fetchedRelationships","_apexConnectionInfo","currentId","currentType","oespControllerUpdateResult","getOrCreateOespControllerWithUpdate","getOwner","apexChannelGuid","SvrPlaybackFeatures","Svr","setPropsFromVideoSource","getSVRStreamingParameters","moreThanOneCameraItem","streamingParams","_videoSource$relation","_videoSource$relation2","included","proxyUrl","janusGatewayUrl","janusToken","iceServers","spsAndPpsRequired","proxyStreamTimeoutTime","coturnAddressesTuplets","visualVerificationRecord","supportsAudioForProxyStream","relationships","proxyWebrtcConnectionInfoRelationship","proxyWebrtcConnectionInfo","_getOespControllerAnd","svrId","OESP","attemptedDirectAndProxy","playerUrl","WebRTC","cameraMaxClipDuration","maxSvrClipDownloadDurationSec","svrMaxClipDuration","maxClipDuration","maxSvrClipUploadDurationSec","hasSvrSchedule","canUploadFrom247ToCloud","OperatorTitle","formattedDateAndTime","formattedStartDate","formattedEndDate","d","formattedStartTime","formattedEndTime","PlaybackOverlay","DeviceNotConnected","isConnectedAndInGap","_this$args$camera","useDownloadAnchor","_this$visualVerificat","supportsClipDownload","supportsThumbnailsDownload","isVisualVerification","canOperatorDownloadClips","pageFeatures","canDownloadClips","ButtonDownload","svrSupportsDownloadingThumbnails","supportsAdvancedVideoSearch","ButtonAdvancedVideoSearch","disableDownloadButton","showDownloadPopover","openeyePlayer_","videoVideoPlayerOverlayPlaybackOverlay_","webrtcPlayer_","State","updatePlaybackStateCommand","isPauseCommand","Init","runControllerCommands","Ended","Paused","Playing","playFrozen","pausedOnInit","BasePlaybackPlayer","BaseVideoPlayer","willDestroyElement","commands","SHOW_MESSAGE","showMessage","CLEAR_MESSAGE","clearMessage","RESUME","PAUSE","SEEK","SET_SPEED","RESET","deviceProperties","firmwareVersion","deviceModel","resolvedCamera","enableAdvancedVideoSearch","supportsAdvancedMotionSearch","showSnapshot","playStartedWasTriggered","snapshotLoaded","doOnPlaybackControllers","playStarted","onPlayPaused","playPaused","onFrozen","attemptProxyReconnection","errorInfo","onErrorHandler","onIceFailure","errorMessage","shouldRestartPlayer","attemptProxy","playEnded","onUrlUpdate","onSnapshotLoaded","_this$player","_this$player4","_this$player$playback","_this$player2","_this$setOEAudioInfo","_this$player3","onClickOutside_","videoVideoStreamingVideoStreamingPlayersOperatorTitle_","videoVideoPlayerLiveViewPlayer_","videoVideoPlayerBasePlaybackPlayer_","VerticalPlayerPadding","ArrowKeysList","ARROW_LEFT_CODE","ARROW_RIGHT_CODE","ARROW_UP_CODE","ARROW_DOWN_CODE","getVideoPlayerDimensions","querySelectorAll","isTheaterModeOrFullScreen","HdAspectRatio","setVideoPlayerDimensions","changePlayerDimensionsSet","playerDimensionsSet","setupKeyPressesForCameraSelection","camerasSelectorIsOpen","_this$cameraItems2","selectedPlayerFocusTrapId","addWeakTrapFocusListener","scopeSelector","escapeCallback","deselectCameraOnGrid","treatArrowsAsTabEvents","oldListenerId","changeActiveCamera","getNumberCamerasInLocation","row","col","_cameraItemsGrid$row","cameraItemsGrid","layoutProperties","layoutType","numRows","numCamerasInRow","numCamerasInCol","_cameraItemsGrid","AutoView","singlePlayer","viewIndexLocationList","selectedCameraLocation","column","firstViewIndexGridLocations","numCamerasInLocation","setNextActiveCamera","setSelectedCameraLocation","currentCamera","_cameraItemsGrid$sele","nextActiveCamera","viewIndex","_cameraItemsGrid$this","directionalValueCol","directionalValueRow","nextRow","nextColumn","getUnfilledHybridGrid","hybridGridDimensions","unfilledCameraGrid","numCols","setViewIndexLocationsAndGridDimensions","isHybridWide","HybridView","OnePlusFiveView","OnePlusSevenView","TwoPlusEightView","FourPlusTwoPlusFourView","VideoStreamingPlayers","didRender","willDestroy","_this$saveCameraGroup","saveCamerasOrderTask","saveCameraGroupOrderFromCamItemsOrder","showOperatorTitle","_this$cameraItems3","isLiveView","containerStyle","bestAutoView","cameraExpanded","dimensions","style","columns","heightPercent","rows","containerClass","isFullScreen","appendStringsIf","appendStrings","isDraggingOverOrigin","draggingOverIndex","draggingOriginIndex","enableDragAndDrop","_this$layoutPropertie","cameraItemsSortedByViewIndex","numCameras","cameraGrid","currentRowArray","currentViewIndex","currentIndexInRow","shouldShowWarningSoundHelpTour","hasShownWarningSoundHelpTour","helpTours","WarningSoundFeatureTour","avsResultSwitchAbility","canGoToNextClip","canGoToPreviousClip","playerTypeSupportsDownloadingThumbnails","supportsDownloadingThumbnailsProperty","cameraItemsObserver","dimensionsChangeObserver","expandCamera","expandCameraIndex","returnToGroup","resetExpandedCameraIndex","swapCamera","cameraToSwap","newViewIndex","_this$onSwapCamera","originalViewIndex","cameraIsMovingDown","camerasToShift","setLargeHybridCamera","_this$cameraItems4","removeTrapFocusListener","_this$downloadThumbna","openDownloadClipModal","_this$downloadClip","_this$playEnded","onSetLoadingPercentage","_this$setLoadingPerce","onUpdatePageAndPlayerState","_this$updatePageAndPl","_this$syncTimer","onAttachToOespController","_this$cameraItems5","playersAttachedToController","_player$component","playbackStateControllerInitCompleted","playersUsingController","attachResumeMethod","method","retryTimedOutMethods","retryAllTimedOutCameras","onDragStart","_this$cameraItems6","_event$dataTransfer","draggingOriginGlobalDeviceId","videoElement","offsetHeight","dataTransfer","setDragImage","onDragOver","onDrop","onDragLeave","inProgress","delete","_this$saveCameraGroup2","KeyDescription","isLarge","ShortcutDescription","keyDescriptions","keyMap","B_KEY","C_KEY","E_KEY","F_KEY","N_KEY","S_KEY","T_KEY","UP_ARROW_KEY","DOWN_ARROW_KEY","ENTER_KEY","ESCAPE_KEY","SHIFT_KEY","TAB_KEY","ShortcutTable","shortcutDescriptions","shortcuts","shortcut","SaveCameraGroup","_this$args$model$came","saveGroup","isNewGroup","cameraIds","peekRecord","updateCameraOrderFromCameras","_model$groupSaved","save","groupSaved","overwriteGroup","selectedCameraGroupId","OverwriteExistingGroup","createNewGroup","createRecord","groupName","CreateNewGroup","willDestroy_","searchInput_","CAMERA_SELECTOR_CSS","cameraIdsMapped","getReasonCameraCannotBeSelected","isExcludedDueToEE","isExcludedDueToVV","supportsLiveView","activateCameraIds","cameraIdsToActivate","setNewActiveCameras","closeDropdown","cachedCameraIdsToActivate","cachedGroupIdToActivate","selectCameraGroup","clearAllTemporaryVariables","cameraSelectorStatusChange","saveCachedCamerasOrGroup","newCachedCameras","newCachedGroup","trapFocusListenerId","clickOutsideOfMenuListener","clearCamerasGroupCache","clickOutsideOfMenuHandler","dropdownMenu","hotKeyHandler","clearSelectedCameras","showNewGroupButton","SaveCameraGroupModal","onSaveGroup","VideoStreamingCamerasSelector","showSearch","dropdownIsOpen","alwaysShowSearch","shownCameraGroups","filterString","latestGroupId","usingCustomCameras","group","groupType","isLiveViewMobileExclusive","camerasCount","camerasCountDescription","count","isLocation","LocationGroup","shownCameras","cameraLocations","latestCameraIds","cameraObjects","excludedCameraObjects","cameraListIsCutOff","reasonCameraCannotBeSelected","canBeSelected","locationDescription","activeCameraIds","cameraObj","showLocations","locations","cameraSelectorHeightStyle","showResetApplyButtons","maxCameraSelectorHeight","pixelAmount","lastSelectedGroup","userIsSelectingCustomCameras","enableResetButton","enableApplyButton","headerText","matchingGroup","camerasCountText","first","second","_cameras$findBy","CameraSelectorResetSelection","updateLastSelectedGroup","toggleDropdown","exitEventEnum","CameraSelectorApply","CameraSelectorClose","addListenersOnDropdownOpen","onSelectCameraGroup","groupId","CameraSelectorGroupSelected","onSelectCamera","isChecked","CameraSelectorToggleCamera","onSelectCameraOnly","CameraSelectorSingleCamera","userCreatedGroups","NormalGroup","selectedGroupId","CameraSelectorSaveSelection","disableBackdropClose","_this$args$groupSaved","filterDevices","handleSpaceOrEnter","isEnterOrSpaceCode","code","isSpaceCode","hotKeyListener","removeHotKeys","videoVideoStreamingVideoStreamingToolbarShortcutTable_","KeyboardShortcutsPopover","LayoutsPopover","LayoutZoomFeatures","videoVideoStreamingVideoStreamingToolbarKeyboardShortcutsPopover_","uppercase_","videoVideoStreamingVideoStreamingToolbarLayoutZoomFeatures_","DisplayOptionsDropdown","clickButton","videoVideoStreamingVideoStreamingToolbarVideoStreamingCamerasSelector_","videoVideoStreamingVideoStreamingToolbarLayoutsPopover_","videoLiveVideoDisplayOptionsDropdown_","selectLayoutType","newLayoutType","_this$args$layoutProp","updateLayoutType","getLayoutChangeEventEnum","resetExpandedCamera","VideoStreamingToolbar","fnEmpty","showManageGroupsButton","isOperatorSession","selectedLayoutsPopoverButton","layoutsPopoverButtons","selectedLayoutButton","layoutButton","showLayoutsPopover","primary","tooltipText","tooltipConcatenator","autoText","text1plus3","text1plus5","text1plus7","text2plus8","text4plus2plus4","cameraCount","visible","layoutIsAllowedForScenario","hdButton","showDropdown","toggleDropdownShortcuts","showDropdownShortcuts","toggleShortcut","showShortcuts","onResize","kbdShortcutButton","keyInfos","textInfo","isGeneric","getKeySection","keyType","keyInfo","cameraShortcuts","playerViewShortcuts","playbackControlShortcuts","selectCameraDropdownShortcuts","datePickerModalShortcuts","viewerLayoutShortcuts","avsControlShortcuts","screenSizeButtons","showHdButton","alwaysHideHdButton","showHdButtonFn","isFullScreenAllowed","toggleFullScreen","toggleTheaterMode","isTheaterMode","makeButton","translationKey","iconType","fnAction","theaterText","theaterIcon","fullScreenText","fullScreenIcon","dropdownCameras","selectableInDropdown","selectLayout","layoutValue","onManageCameraGroupsClick","ManageCameraGroups","onCameraFilterChange","camerasToDisplay","selectableDropdownCameras","setPageNumber","helper","params","p","SvrTimelineController","BasePlaybackController","isMobile","goToAddSchedulesRoute","svrs","availableRoutesIds","VideoAddSvrRecordingSchedule","VideoLocalScheduleDisplayType","localScheduleSuggestions","svrSchedules","suggestion","SvrRecordingSchedule","showSvrScheduleModalFunction","videoScheduleTransitionFunction","errMsg","getCaughtError","EmberEnterpriseVideoThumbnailSearch","EmberVideoThumbnailSearch","VideoThumbnailSearchRoute","AdcBaseRoute","getQueryParam","_params$time","_params$isSdCard","dirtyDate","requiredArgs","setSeconds","startOfMinute","deviceName","id_camera","thumbnailEndpointPromise","thumbnailEndpoint","videoSourcePromise","recordedVideoSource","timeUtc","afterModel","minutesToSeconds","timelineRoute","EmberSDCard","addNotification","transitionBackToMobileAppOrPreviousRoute","stringFunction","isHTMLSafe","createStringHelperFunction","_htmlSafe","uppercase","TypeError","toUpperCase","dirtyAmount","toInteger","secondsInMinute"],"sourceRoot":""}