@xibosignage/xibo-layout-renderer 1.0.2 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/Modules/ActionController/ActionController.d.ts +32 -0
- package/dist/src/Modules/ActionController/index.d.ts +1 -0
- package/dist/src/Modules/Generators/Generators.d.ts +3 -0
- package/dist/src/Types/Layout/Layout.types.d.ts +7 -2
- package/dist/src/Types/Region/Region.types.d.ts +3 -1
- package/dist/styles.css +106 -1
- package/dist/xibo-layout-renderer.cjs.js +419 -6
- package/dist/xibo-layout-renderer.cjs.js.map +1 -1
- package/dist/xibo-layout-renderer.d.ts +40 -3
- package/dist/xibo-layout-renderer.esm.js +419 -6
- package/dist/xibo-layout-renderer.esm.js.map +1 -1
- package/dist/xibo-layout-renderer.js +419 -6
- package/dist/xibo-layout-renderer.min.js +1 -1
- package/dist/xibo-layout-renderer.min.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"xibo-layout-renderer.min.js","sources":["../node_modules/nanoevents/index.js","../../src/Modules/Platform/Platform.ts","../../src/Types/Layout/Layout.types.ts","../../src/Modules/Generators/Generators.ts","../../src/Types/Region/Region.types.ts","../../src/Types/Media/Media.types.ts","../../src/Modules/Transitions/Transitions.ts","../../src/Modules/Media/Media.ts","../../src/Modules/Media/VideoMedia.ts","../../src/Modules/Media/AudioMedia.ts","../../src/Modules/Layout/Layout.ts","../../src/Types/XLR/XLR.types.ts","../../src/Modules/Region/Region.ts","../src/Modules/SplashScreen/img/logo.png","../src/Modules/SplashScreen/img/loader.gif","../../src/xibo-layout-renderer.ts","../../src/Modules/SplashScreen/SplashScreen.ts"],"sourcesContent":["export let createNanoEvents = () => ({\n emit(event, ...args) {\n for (\n let i = 0,\n callbacks = this.events[event] || [],\n length = callbacks.length;\n i < length;\n i++\n ) {\n callbacks[i](...args)\n }\n },\n events: {},\n on(event, cb) {\n ;(this.events[event] ||= []).push(cb)\n return () => {\n this.events[event] = this.events[event]?.filter(i => cb !== i)\n }\n }\n})\n","/*\r\n * Copyright (C) 2024 Xibo Signage Ltd\r\n *\r\n * Xibo - Digital Signage - https://www.xibosignage.com\r\n *\r\n * This file is part of Xibo.\r\n *\r\n * Xibo is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Lesser General Public License as published by\r\n * the Free Software Foundation, either version 3 of the License, or\r\n * any later version.\r\n *\r\n * Xibo is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Lesser General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Lesser General Public License\r\n * along with Xibo. If not, see <http://www.gnu.org/licenses/>.\r\n */\r\nimport {OptionsType} from \"../../Types/Layout\";\r\n\r\nconst RESOURCE_URL = '/playlist/widget/resource/:regionId/:id';\r\nconst XLF_URL = '/layout/xlf/:layoutId';\r\nconst LAYOUT_BACKGROUND_DOWNLOAD_URL = '/layout/background/:id';\r\nconst LAYOUT_PREVIEW_URL = '/layout/preview/[layoutCode]';\r\nconst LIBRARY_DOWNLOAD_URL = '/library/download/:id';\r\nconst LOADER_URL = '/theme/default/img/loader.gif';\r\n\r\nexport const platform: OptionsType = {\r\n getResourceUrl: RESOURCE_URL,\r\n xlfUrl: XLF_URL,\r\n layoutBackgroundDownloadUrl: LAYOUT_BACKGROUND_DOWNLOAD_URL,\r\n layoutPreviewUrl: LAYOUT_PREVIEW_URL,\r\n libraryDownloadUrl: LIBRARY_DOWNLOAD_URL,\r\n loaderUrl: LOADER_URL,\r\n idCounter: 0,\r\n inPreview: true,\r\n appHost: null,\r\n platform: 'CMS',\r\n};\r\n","/*\r\n * Copyright (C) 2024 Xibo Signage Ltd\r\n *\r\n * Xibo - Digital Signage - https://www.xibosignage.com\r\n *\r\n * This file is part of Xibo.\r\n *\r\n * Xibo is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Lesser General Public License as published by\r\n * the Free Software Foundation, either version 3 of the License, or\r\n * any later version.\r\n *\r\n * Xibo is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Lesser General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Lesser General Public License\r\n * along with Xibo. If not, see <http://www.gnu.org/licenses/>.\r\n */\r\nimport {DefaultEvents, Emitter, Unsubscribe} from 'nanoevents';\r\nimport {IRegion} from '../Region';\r\nimport {platform} from '../../Modules/Platform';\r\nimport {ILayoutEvents} from '../../Modules/Layout';\r\nimport {IXlr} from '../XLR';\r\n\r\nexport type InputLayoutType = {\r\n layoutId: number | null;\r\n path?: string;\r\n};\r\n\r\nexport type OptionsType = {\r\n xlfUrl: string;\r\n getResourceUrl: string;\r\n layoutBackgroundDownloadUrl: string;\r\n layoutPreviewUrl: string;\r\n libraryDownloadUrl: string;\r\n loaderUrl: string;\r\n idCounter: number;\r\n inPreview: boolean;\r\n appHost?: string | null;\r\n platform: 'CMS' | 'chromeOS';\r\n config?: {\r\n cmsUrl: string | null;\r\n schemaVersion: number;\r\n cmsKey: string | null;\r\n hardwareKey: string | null;\r\n };\r\n};\r\n\r\nexport interface ILayout {\r\n id: number | null;\r\n layoutId: number | null;\r\n sw: number | null;\r\n sh: number | null;\r\n xw: number | null;\r\n xh: number | null;\r\n zIndex: number | null;\r\n scaleFactor: number;\r\n sWidth: number;\r\n sHeight: number;\r\n offsetX: number;\r\n offsetY: number;\r\n bgColor: string;\r\n bgImage: string;\r\n bgId: string;\r\n containerName: string;\r\n layoutNode: Document | null;\r\n regionMaxZIndex: number;\r\n ready: boolean;\r\n regionObjects: IRegion[];\r\n drawer: String[];\r\n allExpired: boolean;\r\n regions: IRegion[];\r\n actions: String[];\r\n options: OptionsType;\r\n done: boolean;\r\n allEnded: boolean;\r\n path?: string;\r\n prepareLayout(): void;\r\n parseXlf(): void;\r\n run(): void;\r\n emitter: Emitter<ILayoutEvents>;\r\n on<E extends keyof ILayoutEvents>(event: E, callback: ILayoutEvents[E]): Unsubscribe;\r\n regionExpired(): void;\r\n end(): void;\r\n regionEnded(): void;\r\n stopAllMedia(): Promise<void>;\r\n resetLayout(): Promise<void>;\r\n index: number;\r\n}\r\n\r\nexport const initialLayout: ILayout = {\r\n id: null,\r\n layoutId: null,\r\n sw: 0,\r\n sh: 0,\r\n xw: 0,\r\n xh: 0,\r\n zIndex: 0,\r\n scaleFactor: 1,\r\n sWidth: 0,\r\n sHeight: 0,\r\n offsetX: 0,\r\n offsetY: 0,\r\n bgColor: '',\r\n bgImage: '',\r\n bgId: '',\r\n containerName: '',\r\n layoutNode: null,\r\n regionMaxZIndex: 0,\r\n ready: false,\r\n regionObjects: [],\r\n drawer: [],\r\n allExpired: false,\r\n regions: [],\r\n actions: [],\r\n options: platform,\r\n done: false,\r\n allEnded: false,\r\n path: '',\r\n prepareLayout() {\r\n },\r\n parseXlf() {\r\n },\r\n run() {\r\n },\r\n on<E extends keyof ILayoutEvents>(event: E, callback: ILayoutEvents[E]): Unsubscribe {\r\n return <Unsubscribe>{};\r\n },\r\n regionExpired() {\r\n },\r\n end() {\r\n },\r\n regionEnded() {\r\n },\r\n stopAllMedia() {\r\n return Promise.resolve();\r\n },\r\n resetLayout() {\r\n return Promise.resolve();\r\n },\r\n emitter: <Emitter<ILayoutEvents>>{},\r\n index: -1,\r\n};\r\n\r\nexport type GetLayoutParamType = {\r\n xlr: IXlr;\r\n moveNext?: boolean;\r\n}\r\n\r\nexport type GetLayoutType = {\r\n currentLayoutIndex: number;\r\n inputLayouts: InputLayoutType[];\r\n current: ILayout | undefined;\r\n next: ILayout | undefined;\r\n}\r\n","/*\r\n * Copyright (C) 2024 Xibo Signage Ltd\r\n *\r\n * Xibo - Digital Signage - https://www.xibosignage.com\r\n *\r\n * This file is part of Xibo.\r\n *\r\n * Xibo is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Lesser General Public License as published by\r\n * the Free Software Foundation, either version 3 of the License, or\r\n * any later version.\r\n *\r\n * Xibo is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Lesser General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Lesser General Public License\r\n * along with Xibo. If not, see <http://www.gnu.org/licenses/>.\r\n */\r\nimport { IMedia } from '../../Types/Media';\r\nimport {InputLayoutType, OptionsType} from '../../Types/Layout';\r\n\r\nexport function nextId(options: { idCounter: number; }) {\r\n if (options.idCounter > 500) {\r\n options.idCounter = 0;\r\n }\r\n\r\n options.idCounter = options.idCounter + 1;\r\n return options.idCounter;\r\n}\r\n\r\nexport const getMediaId = ({mediaType, containerName}: IMedia) => {\r\n let mediaId = containerName;\r\n\r\n if (mediaType === 'video') {\r\n mediaId = mediaId + '-vid';\r\n } else if (mediaType === 'audio') {\r\n mediaId = mediaId + '-aud';\r\n }\r\n\r\n return mediaId;\r\n};\r\n\r\nexport const capitalizeStr = (inputStr: string) => {\r\n if (inputStr === null) {\r\n return '';\r\n }\r\n\r\n return String(inputStr).charAt(0).toUpperCase() + String(inputStr).substring(1);\r\n};\r\n\r\nexport async function getDataBlob(src: string) {\r\n return fetch(src, {mode: 'no-cors'})\r\n .then((res) => res.blob())\r\n .then((blob) => new Promise((res, rej) => {\r\n const reader = new FileReader();\r\n\r\n reader.onloadend = () => res(reader.result);\r\n reader.onerror = rej;\r\n reader.readAsDataURL(blob);\r\n }));\r\n}\r\n\r\nexport async function preloadMediaBlob(src: string, type: 'video' | 'audio' | 'image') {\r\n const res = await fetch(src, {mode: 'no-cors'});\r\n let blob: Blob | MediaSource = new Blob();\r\n\r\n if (type === 'image') {\r\n blob = new Blob()\r\n } else if (type === 'video') {\r\n blob = await res.blob();\r\n } else if (type === 'audio') {\r\n const data = await res.arrayBuffer();\r\n blob = new Blob([data], { type: audioFileType(getFileExt(src)) })\r\n }\r\n\r\n return URL.createObjectURL(blob);\r\n}\r\n\r\nexport async function fetchJSON(url: string) {\r\n return fetch(url)\r\n .then(res => res.json())\r\n .catch(err => {\r\n console.debug(err);\r\n });\r\n}\r\n\r\nexport async function fetchText(url: string): Promise<string> {\r\n return fetch(url)\r\n .then(res => res.text())\r\n .then((responseText) => {\r\n if (String(responseText).length > 0) {\r\n return responseText;\r\n } else {\r\n return '';\r\n }\r\n })\r\n .catch(err => {\r\n console.debug(err);\r\n return err?.message;\r\n });\r\n}\r\n\r\nexport function getFileExt(filename: string) {\r\n const filenameArr = String(filename).split('.');\r\n\r\n return filenameArr[filenameArr.length - 1];\r\n}\r\n\r\nexport function audioFileType(str: string) {\r\n const validAudioTypes = {\r\n 'mp3': 'audio/mp3',\r\n 'wav': 'audio/wav',\r\n 'ogg': 'audio/ogg',\r\n };\r\n\r\n if (Boolean(validAudioTypes[str as 'mp3' | 'wav' | 'ogg'])) {\r\n return validAudioTypes[str as 'mp3' | 'wav' | 'ogg'];\r\n }\r\n\r\n return undefined;\r\n}\r\n\r\nexport function composeResourceUrlByPlatform(options: OptionsType, params: any) {\r\n let resourceUrl = params.regionOptions.getResourceUrl\r\n .replace(\":regionId\", params.regionId)\r\n .replace(\":id\", params.mediaId) +\r\n '?preview=1&layoutPreview=1';\r\n\r\n if (options.platform === 'chromeOS') {\r\n const resourceEndpoint = '/required-files/resource/';\r\n\r\n if (!params.isGlobalContent && params.isImageOrVideo) {\r\n resourceUrl = resourceEndpoint + params.fileId + '?saveAs=' + params.uri;\r\n }\r\n } else if (!Boolean(params['mediaType'])) {\r\n resourceUrl += '&scale_override=' + params.scaleFactor;\r\n }\r\n\r\n return resourceUrl;\r\n}\r\n\r\nexport function composeResourceUrl(options: OptionsType, params: any) {\r\n const schemaVersion = (options) && options.config?.schemaVersion;\r\n const hardwareKey = (options) && options.config?.hardwareKey;\r\n const serverKey = (options) && options.config?.cmsKey;\r\n\r\n return '/pwa/getResource' +\r\n '?v=' + schemaVersion +\r\n '&serverKey=' + serverKey +\r\n '&hardwareKey=' + hardwareKey +\r\n '&layoutId=' + params.layoutId +\r\n '®ionId=' + params.regionId +\r\n '&mediaId=' + params.mediaId;\r\n}\r\n\r\nexport function composeVideoUrl(params: any) {\r\n return '/xmds.php?file=' + params.uri;\r\n}\r\n\r\nexport function composeBgUrlByPlatform(\r\n platform: OptionsType['platform'],\r\n params: any\r\n) {\r\n let bgImageUrl = params.layoutBackgroundDownloadUrl.replace(\":id\", (params.layout.id as unknown) as string) +\r\n '?preview=1&width=' + params.layout.sWidth +\r\n '&height=' + params.layout.sHeight +\r\n '&dynamic&proportional=0';\r\n\r\n if (platform === 'chromeOS') {\r\n bgImageUrl = '/required-files/resource/' + params.layout.id +\r\n '?saveAs=' + params.layout.bgImage;\r\n }\r\n\r\n return bgImageUrl;\r\n}\r\n\r\ntype LayoutIndexType = {\r\n [k: string]: InputLayoutType & {\r\n index: number;\r\n }\r\n}\r\n\r\nexport function getIndexByLayoutId(layoutsInput: InputLayoutType[], layoutId?: number | null) {\r\n let layoutIndexes = layoutsInput.reduce((a: LayoutIndexType, b, indx) => {\r\n a[Number(b.layoutId)] = {\r\n ...b,\r\n index: indx\r\n };\r\n\r\n return a;\r\n }, {});\r\n\r\n if (layoutId === null || !layoutId) {\r\n return layoutIndexes;\r\n }\r\n\r\n if (Boolean(layoutIndexes[layoutId])) {\r\n return layoutIndexes[layoutId];\r\n }\r\n\r\n // Defaults to 0\r\n return {index: 0};\r\n}\r\n\r\nexport function isEmpty(input: any) {\r\n return !Boolean(input) || String(input).length === 0;\r\n}\r\n\r\nexport const splashScreenLayoutObj: InputLayoutType = {\r\n layoutId: 0,\r\n path: '',\r\n};\r\n\r\nexport function splashScreenDOM() {\r\n const mediaItem = document.querySelector('.media--item');\r\n const newImg = document.createElement('img');\r\n\r\n newImg.src = new URL('./logo.png', import.meta.url).href;\r\n\r\n if (mediaItem !== null) {\r\n mediaItem.insertBefore(newImg, mediaItem.lastElementChild);\r\n }\r\n\r\n return newImg;\r\n}\r\n","/*\r\n * Copyright (C) 2024 Xibo Signage Ltd\r\n *\r\n * Xibo - Digital Signage - https://www.xibosignage.com\r\n *\r\n * This file is part of Xibo.\r\n *\r\n * Xibo is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Lesser General Public License as published by\r\n * the Free Software Foundation, either version 3 of the License, or\r\n * any later version.\r\n *\r\n * Xibo is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Lesser General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Lesser General Public License\r\n * along with Xibo. If not, see <http://www.gnu.org/licenses/>.\r\n */\r\nimport { DefaultEvents, Emitter, Unsubscribe } from 'nanoevents';\r\nimport {ILayout, initialLayout} from '../Layout';\r\nimport {IMedia} from '../Media';\r\n\r\nexport interface IRegionEvents {\r\n start: (layout: IRegion) => void;\r\n end: (layout: IRegion) => void;\r\n}\r\n\r\nexport interface IRegion {\r\n layout: ILayout;\r\n id: string;\r\n regionId: string;\r\n xml: null | Element;\r\n mediaObjects: IMedia[];\r\n mediaObjectsActions: String[];\r\n currentMedia: number;\r\n complete: boolean;\r\n containerName: string;\r\n ending: boolean;\r\n ended: boolean;\r\n oneMedia: boolean;\r\n oldMedia: IMedia | undefined;\r\n curMedia: IMedia | undefined;\r\n nxtMedia: IMedia | undefined;\r\n currentMediaIndex: number;\r\n totalMediaObjects: number;\r\n ready: boolean;\r\n options: {\r\n [k: string]: any;\r\n };\r\n sWidth: number;\r\n sHeight: number;\r\n offsetX: number;\r\n offsetY: number;\r\n zIndex: number;\r\n index: number;\r\n emitter?: Emitter<DefaultEvents>;\r\n prepareRegion(): void;\r\n playNextMedia(): void;\r\n transitionNodes(oldMedia: IMedia | undefined, newMedia: IMedia | undefined): void;\r\n finished(): void;\r\n run(): void;\r\n end(): void;\r\n exitTransition(): void;\r\n exitTransitionComplete(): void;\r\n on<E extends keyof IRegionEvents>(event: E, callback: IRegionEvents[E]): Unsubscribe;\r\n prepareMediaObjects(): void;\r\n reset(): void;\r\n}\r\n\r\nexport const initialRegion: IRegion = {\r\n layout: initialLayout,\r\n id: '',\r\n regionId: '',\r\n xml: null,\r\n mediaObjects: [],\r\n mediaObjectsActions: [],\r\n currentMedia: -1,\r\n complete: false,\r\n containerName: '',\r\n ending: false,\r\n ended: false,\r\n oneMedia: false,\r\n oldMedia: undefined,\r\n curMedia: undefined,\r\n nxtMedia: undefined,\r\n currentMediaIndex: 0,\r\n totalMediaObjects: 0,\r\n ready: false,\r\n options: {},\r\n sWidth: 0,\r\n sHeight: 0,\r\n offsetX: 0,\r\n offsetY: 0,\r\n zIndex: 0,\r\n index: -1,\r\n prepareRegion() {\r\n },\r\n playNextMedia() {\r\n },\r\n transitionNodes() {\r\n },\r\n finished() {\r\n },\r\n run() {\r\n },\r\n end() {\r\n },\r\n exitTransition() {},\r\n exitTransitionComplete() {},\r\n on<E extends keyof IRegionEvents>(event: E, callback: IRegionEvents[E]): Unsubscribe {\r\n return <Unsubscribe>{};\r\n },\r\n prepareMediaObjects() {\r\n },\r\n reset() {\r\n }\r\n};\r\n","/*\r\n * Copyright (C) 2024 Xibo Signage Ltd\r\n *\r\n * Xibo - Digital Signage - https://www.xibosignage.com\r\n *\r\n * This file is part of Xibo.\r\n *\r\n * Xibo is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Lesser General Public License as published by\r\n * the Free Software Foundation, either version 3 of the License, or\r\n * any later version.\r\n *\r\n * Xibo is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Lesser General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Lesser General Public License\r\n * along with Xibo. If not, see <http://www.gnu.org/licenses/>.\r\n */\r\nimport {Emitter, Unsubscribe} from 'nanoevents';\r\nimport { IMediaEvents } from '../../Modules/Media/Media';\r\nimport {initialRegion, IRegion} from '../Region';\r\nimport {OptionsType} from '../Layout';\r\n\r\nexport interface IMedia {\r\n checkIframeStatus: boolean;\r\n run(): void;\r\n divHeight: number;\r\n type: string;\r\n timeoutId: ReturnType<typeof setTimeout>;\r\n divWidth: number;\r\n tempSrc: string;\r\n duration: number;\r\n iframeName: string;\r\n loadIframeOnRun: boolean;\r\n xml: Element | null;\r\n containerName: string;\r\n ready: boolean;\r\n loop: boolean;\r\n options: OptionsType & {\r\n [k: string]: any\r\n };\r\n useDuration: boolean;\r\n html: HTMLElement | null;\r\n id: string;\r\n mediaId: string;\r\n iframe: HTMLIFrameElement | null;\r\n render: string;\r\n attachedAudio: boolean;\r\n on<E extends keyof IMediaEvents>(event: E, callback: IMediaEvents[E]): Unsubscribe;\r\n init(): void;\r\n schemaVersion: string;\r\n index: number;\r\n mediaType: string;\r\n finished: boolean;\r\n uri: string;\r\n url: string | null;\r\n singlePlay: boolean;\r\n stop(): Promise<void>;\r\n idCounter: number;\r\n region: IRegion;\r\n fileId: string;\r\n emitter: Emitter<IMediaEvents>;\r\n}\r\n\r\nexport const initialMedia: IMedia = {\r\n region: initialRegion,\r\n xml: null,\r\n id: '',\r\n mediaId: '',\r\n index: 0,\r\n idCounter: 0,\r\n containerName: '',\r\n html: null,\r\n iframe: null,\r\n iframeName: '',\r\n mediaType: '',\r\n render: 'html',\r\n attachedAudio: false,\r\n singlePlay: false,\r\n timeoutId: setTimeout(() => {}, 0),\r\n ready: true,\r\n checkIframeStatus: false,\r\n loadIframeOnRun: false,\r\n tempSrc: '',\r\n finished: false,\r\n schemaVersion: '1',\r\n type: '',\r\n duration: 0,\r\n useDuration: Boolean(0),\r\n fileId: '',\r\n uri: '',\r\n options: <OptionsType>{},\r\n divWidth: 0,\r\n divHeight: 0,\r\n url: null,\r\n loop: false,\r\n run() {},\r\n init() {},\r\n stop() {\r\n return Promise.resolve();\r\n },\r\n on<E extends keyof IMediaEvents>(event: E, callback: IMediaEvents[E]): Unsubscribe {\r\n return <Unsubscribe>{};\r\n },\r\n emitter: <Emitter<IMediaEvents>>{},\r\n}\r\n","/*\n * Copyright (C) 2024 Xibo Signage Ltd\n *\n * Xibo - Digital Signage - https://www.xibosignage.com\n *\n * This file is part of Xibo.\n *\n * Xibo is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Lesser General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * any later version.\n *\n * Xibo is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * along with Xibo. If not, see <http://www.gnu.org/licenses/>.\n */\nexport const defaultTrans = (duration: number, trans: 'in' | 'out') => {\n const defaultKeyframes = [\n { display: trans === 'in' ? 'none' : 'block' },\n { display: trans === 'out' ? 'none' : 'block' },\n ];\n const defaultTiming: number | KeyframeAnimationOptions | undefined = {\n duration,\n };\n\n return {\n keyframes: defaultKeyframes,\n timing: defaultTiming,\n };\n};\n\nexport const fadeInElem = (duration: number) => {\n const fadeInKeyframes = [\n { opacity: 0 },\n { opacity: 1 },\n ];\n const fadeInTiming: number | KeyframeAnimationOptions | undefined = {\n duration,\n fill: 'forwards',\n };\n\n return {\n keyframes: fadeInKeyframes,\n timing: fadeInTiming,\n }\n};\n\nexport const fadeOutElem = (duration: number) => {\n const fadeOutKeyframes = [\n { opacity: 1 },\n { opacity: 0, zIndex: -1 },\n ];\n const fadeOutTiming: number | KeyframeAnimationOptions | undefined = {\n duration,\n fill: 'forwards',\n };\n\n return {\n keyframes: fadeOutKeyframes,\n timing: fadeOutTiming,\n }\n};\n\nexport type KeyframeOptionsType = {\n from: {\n [k: string]: any,\n },\n to: {\n [k: string]: any,\n },\n}\n\nexport const flyInElem = (duration: number, keyframeOptions: KeyframeOptionsType | undefined, direction?: string) => {\n const flyInKeyframes = [\n {opacity: 0},\n {opacity: 1, zIndex: 1},\n ];\n const flyInTiming: number | KeyframeAnimationOptions | undefined = {\n duration,\n fill: 'forwards',\n };\n\n if (keyframeOptions && Boolean(keyframeOptions.from)) {\n flyInKeyframes[0] = {...keyframeOptions.from, ...flyInKeyframes[0]};\n }\n\n if (keyframeOptions && Boolean(keyframeOptions.to)) {\n flyInKeyframes[1] = {...keyframeOptions.to, ...flyInKeyframes[1]};\n }\n\n return {\n keyframes: flyInKeyframes,\n timing: flyInTiming,\n };\n};\n\nexport const flyOutElem = (duration: number, keyframeOptions: KeyframeOptionsType | undefined, direction?: string) => {\n const flyOutKeyframes: Keyframe[] = [\n {opacity: 1},\n {opacity: 0, zIndex: -1},\n ];\n const flyOutTiming: number | KeyframeAnimationOptions | undefined = {\n duration,\n fill: 'forwards',\n };\n\n if (keyframeOptions && Boolean(keyframeOptions.from)) {\n flyOutKeyframes[0] = {...keyframeOptions.from, ...flyOutKeyframes[0]};\n }\n\n if (keyframeOptions && Boolean(keyframeOptions.to)) {\n flyOutKeyframes[1] = {...keyframeOptions.to, ...flyOutKeyframes[1]};\n }\n\n return {\n keyframes: flyOutKeyframes,\n timing: flyOutTiming,\n };\n};\n\nexport type TransitionNameType = 'fadeIn' | 'fadeOut' | 'flyIn' | 'flyOut' | 'defaultIn' | 'defaultOut';\n\nexport type TransitionElementOptions = {\n duration: number;\n keyframes?: KeyframeOptionsType;\n direction?: string;\n};\n\nexport const transitionElement = (transition: TransitionNameType, options: TransitionElementOptions) => {\n const transitions = {\n fadeIn: fadeInElem(options.duration),\n fadeOut: fadeOutElem(options.duration),\n flyIn: flyInElem(options.duration, options.keyframes, options.direction),\n flyOut: flyOutElem(options.duration, options.keyframes, options.direction),\n defaultIn: defaultTrans(options.duration, 'in'),\n defaultOut: defaultTrans(options.duration, 'out'),\n };\n\n return transitions[transition];\n};\n\nexport type compassPoints = 'N' | 'NE' | 'E' | 'SE' | 'S' | 'SW' | 'W' | 'NW';\n\nexport type flyTransitionParams = {\n trans: 'in' | 'out';\n direction: compassPoints;\n height: string | number;\n width: string | number;\n};\n\nexport const flyTransitionKeyframes = (params: flyTransitionParams): KeyframeOptionsType => {\n const keyframes = {\n from: {},\n to: {},\n };\n const opacityAttr = (source: 'from' | 'to') => {\n if (source === 'from') {\n return params.trans === 'in' ? 0 : 1;\n }\n \n return params.trans === 'out' ? 1 : 0;\n };\n\n switch (params.direction) {\n case 'N':\n keyframes.from = {\n opacity: opacityAttr('from'),\n top: params.trans === 'in' ? `${params.height}px` : 0,\n };\n keyframes.to = {\n opacity: opacityAttr('to'),\n top: params.trans === 'in' ? 0 : `-${params.height}px`,\n };\n break;\n case 'NE':\n keyframes.from = {\n opacity: opacityAttr('from'),\n top: params.trans === 'in' ? `${params.height}px` : 0,\n left: params.trans === 'in' ? `-${params.width}px` : 0,\n };\n keyframes.to = {\n opacity: opacityAttr('to'),\n top: params.trans === 'in' ? 0 : `-${params.height}px`,\n left: params.trans === 'in' ? 0 : `${params.width}px`,\n };\n break;\n case 'E':\n keyframes.from = {\n opacity: opacityAttr('from'),\n left: params.trans === 'in' ? `-${params.width}px` : 0,\n };\n keyframes.to = {\n opacity: opacityAttr('to'),\n left: params.trans === 'in' ? 0 : `${params.width}px`,\n };\n break;\n case 'SE':\n keyframes.from = {\n opacity: opacityAttr('from'),\n top: params.trans === 'in' ? `-${params.height}px` : 0,\n left: params.trans === 'in' ? `-${params.width}px` : 0,\n };\n keyframes.to = {\n opacity: opacityAttr('to'),\n top: params.trans === 'in' ? 0 : `${params.height}px`,\n left: params.trans === 'in' ? 0 : `${params.width}px`,\n };\n break;\n case 'S':\n keyframes.from = {\n opacity: opacityAttr('from'),\n top: params.trans === 'in' ? `-${params.height}px` : 0,\n };\n keyframes.to = {\n opacity: opacityAttr('to'),\n top: params.trans === 'in' ? 0 : `${params.height}px`,\n };\n break;\n case 'SW':\n keyframes.from = {\n opacity: opacityAttr('from'),\n top: params.trans === 'in' ? `-${params.height}px` : 0,\n left: params.trans === 'in' ? `${params.width}px` : 0,\n };\n keyframes.to = {\n opacity: opacityAttr('to'),\n top: params.trans === 'in' ? 0 : `${params.height}px`,\n left: params.trans === 'in' ? 0 : `-${params.width}px`,\n };\n break;\n case 'W':\n keyframes.from = {\n opacity: opacityAttr('from'),\n left: params.trans === 'in' ? `${params.width}px` : 0,\n };\n keyframes.to = {\n opacity: opacityAttr('to'),\n left: params.trans === 'in' ? 0 : `-${params.width}px`,\n };\n break;\n case 'NW':\n keyframes.from = {\n opacity: opacityAttr('from'),\n top: params.trans === 'in' ? `${params.height}px` : 0,\n left: params.trans === 'in' ? `${params.width}px` : 0,\n };\n keyframes.to = {\n opacity: opacityAttr('to'),\n top: params.trans === 'in' ? 0 : `-${params.height}px`,\n left: params.trans === 'in' ? 0 : `-${params.width}px`,\n };\n break;\n default:\n keyframes.from = {\n opacity: opacityAttr('from'),\n top: params.trans === 'in' ? `${params.height}px` : 0,\n };\n keyframes.to = {\n opacity: opacityAttr('to'),\n top: params.trans === 'in' ? 0 : `-${params.height}px`,\n };\n break;\n }\n\n return keyframes;\n};\n","/*\r\n * Copyright (C) 2024 Xibo Signage Ltd\r\n *\r\n * Xibo - Digital Signage - https://www.xibosignage.com\r\n *\r\n * This file is part of Xibo.\r\n *\r\n * Xibo is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Lesser General Public License as published by\r\n * the Free Software Foundation, either version 3 of the License, or\r\n * any later version.\r\n *\r\n * Xibo is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Lesser General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Lesser General Public License\r\n * along with Xibo. If not, see <http://www.gnu.org/licenses/>.\r\n */\r\nimport { createNanoEvents } from 'nanoevents';\r\nimport { OptionsType } from '../../Types/Layout';\r\nimport { IRegion } from '../../Types/Region';\r\nimport { IMedia, initialMedia } from '../../Types/Media';\r\nimport { fetchJSON, getMediaId, nextId, preloadMediaBlob } from '../Generators';\r\nimport { TransitionElementOptions, compassPoints, flyTransitionKeyframes, transitionElement } from '../Transitions';\r\nimport VideoMedia from './VideoMedia';\r\nimport AudioMedia from './AudioMedia';\r\nimport {composeResourceUrl, composeResourceUrlByPlatform, composeVideoUrl, fetchText, getDataBlob} from '../Generators/Generators';\r\nimport {IXlr} from '../../Types/XLR';\r\n\r\nexport interface IMediaEvents {\r\n start: (media: IMedia) => void;\r\n end: (media: IMedia) => void;\r\n}\r\n\r\nexport default function Media(\r\n region: IRegion,\r\n mediaId: string,\r\n xml: Element,\r\n options: OptionsType,\r\n xlr: IXlr,\r\n) {\r\n const props = {\r\n region: region,\r\n mediaId: mediaId,\r\n xml: xml,\r\n options: options,\r\n };\r\n let mediaTimer: string | number | NodeJS.Timeout | null | undefined = null;\r\n let mediaTimeCount = 0;\r\n const emitter = createNanoEvents<IMediaEvents>();\r\n const mediaObject: IMedia = {\r\n ...initialMedia,\r\n ...props,\r\n };\r\n const startMediaTimer = (media: IMedia) => {\r\n mediaTimer = setInterval(() => {\r\n mediaTimeCount++;\r\n if (mediaTimeCount > media.duration) {\r\n media.emitter.emit('end', media);\r\n }\r\n }, 1000);\r\n\r\n console.debug('Showing Media ' + media.id + ' for ' + media.duration + 's of Region ' + media.region.regionId);\r\n };\r\n\r\n emitter.on('start', function(media: IMedia) {\r\n if (media.mediaType === 'video') {\r\n VideoMedia(media).init();\r\n\r\n if (media.duration > 0) {\r\n startMediaTimer(media);\r\n }\r\n } else if (media.mediaType === 'audio') {\r\n AudioMedia(media).init();\r\n if (media.duration > 0) {\r\n startMediaTimer(media);\r\n }\r\n } else {\r\n startMediaTimer(media);\r\n }\r\n });\r\n\r\n emitter.on('end', function(media) {\r\n if (mediaTimer) {\r\n clearInterval(mediaTimer);\r\n mediaTimeCount = 0;\r\n }\r\n\r\n media.region.playNextMedia();\r\n });\r\n\r\n mediaObject.on = function<E extends keyof IMediaEvents>(event: E, callback: IMediaEvents[E]) {\r\n return emitter.on(event, callback);\r\n };\r\n\r\n mediaObject.emitter = emitter;\r\n\r\n mediaObject.init = function() {\r\n const self = mediaObject;\r\n self.id = props.mediaId;\r\n self.fileId = self.xml?.getAttribute('fileId') || '';\r\n self.idCounter = nextId(props.options);\r\n self.containerName = `M-${self.id}-${self.idCounter}`;\r\n self.iframeName = `${self.containerName}-iframe`;\r\n self.mediaType = self.xml?.getAttribute('type') || '';\r\n self.render = self.xml?.getAttribute('render') || '';\r\n self.duration = parseInt(self.xml?.getAttribute('duration') as string) || 0;\r\n self.options = { ...props.options };\r\n\r\n const $mediaIframe = document.createElement('iframe');\r\n const mediaOptions = self.xml?.getElementsByTagName('options');\r\n\r\n if (mediaOptions) {\r\n for (let _options of Array.from(mediaOptions)) {\r\n // Get options\r\n const _mediaOptions = _options.children;\r\n for (let mediaOption of Array.from(_mediaOptions)) {\r\n self.options[mediaOption.nodeName.toLowerCase()] = mediaOption.textContent;\r\n }\r\n }\r\n }\r\n\r\n // Check for options.uri and add it to media\r\n if (Boolean(self.options['uri'])) {\r\n self.uri = self.options['uri'];\r\n }\r\n\r\n // Show in fullscreen?\r\n if(self.options.showfullscreen === \"1\") {\r\n // Set dimensions as the layout ones\r\n self.divWidth = self.region.layout.sWidth;\r\n self.divHeight = self.region.layout.sHeight;\r\n } else {\r\n // Set dimensions as the region ones\r\n self.divWidth = self.region.sWidth;\r\n self.divHeight = self.region.sHeight;\r\n }\r\n\r\n $mediaIframe.scrolling = 'no';\r\n $mediaIframe.id = self.iframeName;\r\n $mediaIframe.width = `${self.divWidth}px`;\r\n $mediaIframe.height = `${self.divHeight}px`;\r\n $mediaIframe.style.cssText = `border: 0;`;\r\n\r\n const $mediaId = getMediaId(self);\r\n let $media = document.getElementById($mediaId);\r\n\r\n if ($media === null) {\r\n if (self.mediaType === 'video') {\r\n $media = document.createElement('video');\r\n } else if (self.mediaType === 'audio') {\r\n $media = new Audio();\r\n } else {\r\n $media = document.createElement('div');\r\n }\r\n \r\n $media.id = $mediaId;\r\n }\r\n\r\n $media.className = 'media--item';\r\n\r\n /* Scale the Content Container */\r\n $media.style.cssText = `\r\n display: none;\r\n width: ${self.divWidth}px;\r\n height: ${self.divHeight}px;\r\n position: absolute;\r\n background-size: contain;\r\n background-repeat: no-repeat;\r\n background-position: center;\r\n `;\r\n\r\n const $region = document.getElementById(`${self.region.containerName}`);\r\n\r\n const resourceUrlParams: any = {\r\n ...xlr.config.config,\r\n regionOptions: self.region.options,\r\n layoutId: self.region.layout.layoutId,\r\n regionId: self.region.id,\r\n mediaId: self.id,\r\n fileId: self.fileId,\r\n scaleFactor: self.region.layout.scaleFactor,\r\n uri: self.uri,\r\n isGlobalContent: self.mediaType === 'global',\r\n isImageOrVideo: self.mediaType === 'image' || self.mediaType === 'video',\r\n };\r\n\r\n if (self.mediaType === 'image' || self.mediaType === 'video') {\r\n resourceUrlParams.mediaType = self.mediaType;\r\n }\r\n\r\n let tmpUrl = '';\r\n\r\n if (xlr.config.platform === 'CMS') {\r\n tmpUrl = composeResourceUrlByPlatform(xlr.config, resourceUrlParams);\r\n } else if (xlr.config.platform === 'chromeOS') {\r\n tmpUrl = composeResourceUrl(xlr.config, resourceUrlParams);\r\n\r\n if (self.mediaType === 'video') {\r\n tmpUrl = composeVideoUrl(resourceUrlParams);\r\n }\r\n }\r\n\r\n self.url = tmpUrl;\r\n\r\n // Loop if media has loop, or if region has loop and a single media\r\n self.loop =\r\n self.options['loop'] == '1' ||\r\n (self.region.options['loop'] == '1' && self.region.totalMediaObjects == 1);\r\n\r\n if (self.render === 'html' || self.render === 'webpage') {\r\n $mediaIframe.src = self.url;\r\n } else {\r\n $mediaIframe.src = `${self.url}&width=${self.divWidth}&height=${self.divHeight}`;\r\n }\r\n\r\n // Check/set iframe based widgets play status\r\n // Populate mediaIframe content without using src attribute\r\n // let iframeSrc = tmpUrl;\r\n //\r\n // if (self.render !== 'html' && self.render !== 'webpage') {\r\n // iframeSrc = `${tmpUrl}&width=${self.divWidth}&height=${self.divHeight}`;\r\n // }\r\n //\r\n // if (self.render === 'html' || self.render === 'webpage') {\r\n // if (xlr.config.platform === 'CMS') {\r\n // $mediaIframe.src = iframeSrc;\r\n // } else if (xlr.config.platform === 'chromeOS') {\r\n // (async () => {\r\n // const mediaHtml = await fetchText(iframeSrc);\r\n //\r\n // if ($mediaIframe) {\r\n // $mediaIframe.contentDocument?.open();\r\n // $mediaIframe.contentDocument?.write(mediaHtml);\r\n // $mediaIframe.contentDocument?.close();\r\n // }\r\n // })();\r\n // }\r\n // }\r\n\r\n if (self.render === 'html' || self.mediaType === 'ticker' || self.mediaType === 'webpage') {\r\n self.checkIframeStatus = true;\r\n self.iframe = $mediaIframe;\r\n } else if (self.mediaType === \"image\") {\r\n if (self.options['scaletype'] === 'stretch') {\r\n $media.style.cssText = $media.style.cssText.concat(`background-size: 100% 100%;`);\r\n } else if (self.options['scaletype'] === 'fit') {\r\n $media.style.cssText = $media.style.cssText.concat(`background-size: cover;`);\r\n } else {\r\n // Center scale type, do we have align or valign?\r\n const align = (self.options['align'] == \"\") ? \"center\" : self.options['align'];\r\n const valign = (self.options['valign'] == \"\" || self.options['valign'] == \"middle\") ? \"center\" : self.options['valign'];\r\n $media.style.cssText = $media.style.cssText.concat(`background-position: ${align} ${valign}`);\r\n }\r\n } else if (self.mediaType === 'video') {\r\n const $videoMedia = $media as HTMLVideoElement;\r\n\r\n $videoMedia.preload = 'auto';\r\n $videoMedia.textContent = 'Unsupported Video';\r\n\r\n if (Boolean(self.options['mute'])) {\r\n $videoMedia.muted = self.options.mute === '1';\r\n }\r\n\r\n if (Boolean(self.options['scaletype'])) {\r\n if (self.options.scaletype === 'stretch') {\r\n $videoMedia.style.objectFit = 'fill';\r\n }\r\n }\r\n $videoMedia.playsInline = true;\r\n\r\n if (self.loop) {\r\n $videoMedia.loop = true;\r\n }\r\n\r\n $media = $videoMedia;\r\n } else if (self.mediaType === 'audio') {\r\n const $audioMedia = $media as HTMLAudioElement;\r\n\r\n $audioMedia.preload = 'auto';\r\n $audioMedia.textContent = 'Unsupported Audio';\r\n $audioMedia.autoplay = true;\r\n\r\n if (self.loop) {\r\n $audioMedia.loop = true;\r\n }\r\n\r\n $media = $audioMedia;\r\n }\r\n\r\n // Duration is per item condition\r\n if (self.render === 'html' || self.mediaType === 'ticker') {\r\n /* Check if the ticker duration is based on the number of items in the feed */\r\n if (self.options['durationisperitem'] === '1') {\r\n const regex = new RegExp('<!-- NUMITEMS=(.*?) -->');\r\n\r\n (async () => {\r\n let html = await fetchJSON(`${tmpUrl}&width=${self.divWidth}&height=${self.divHeight}`);\r\n console.debug({html});\r\n const res = regex.exec(html);\r\n\r\n if (res !== null) {\r\n self.duration = parseInt(String(self.duration)) * parseInt(res[1]);\r\n }\r\n })();\r\n }\r\n }\r\n\r\n // Check if the media has fade-in/out transitions\r\n if (Boolean(self.options['transin']) && Boolean(self.options['transinduration'])) {\r\n const transInDuration = Number(self.options.transinduration);\r\n const fadeInTrans = transitionElement('fadeIn', { duration: transInDuration });\r\n $media.animate(fadeInTrans.keyframes, fadeInTrans.timing);\r\n }\r\n\r\n // Add media to the region\r\n // Second media if exists, will be off-canvas\r\n // All added media will be hidden by default\r\n // It will start showing when region.nextMedia() function is called\r\n\r\n // When there's only 1 item and loop = false, don't remove the item but leave it at its last state\r\n // For image, and only 1 item, it should still have the transition for next state\r\n // Add conditions for video duration being 0 or 1 and also the loop property\r\n // For video url, we have to create a URL out of the XLF video URL\r\n\r\n /**\r\n * @DONE\r\n * Case 1: Video duration = 0, this will play the video for its entire duration\r\n * Case 2: Video duration is set > 0 and loop = false\r\n * E.g. Set duration = 100s, video duration = 62s\r\n * the video will play until 62s and will stop to its last frame until 100s\r\n * After 100s, it will expire\r\n * Case 3: Video duration is set > 0 and loop = true\r\n * E.g. Set duration = 100s, video duration = 62s, loop = true\r\n * the video will play until 62s and will loop through until the remaining 38s\r\n * to complete the 100s set duration\r\n */\r\n\r\n // Add html node to media for\r\n self.html = $media;\r\n };\r\n\r\n mediaObject.run = function() {\r\n const self = this;\r\n let transInDuration = 1;\r\n let transInDirection: compassPoints = 'E';\r\n\r\n if (Boolean(self.options['transinduration'])) {\r\n transInDuration = Number(self.options.transinduration);\r\n }\r\n\r\n if (Boolean(self.options['transindirection'])) {\r\n transInDirection = self.options.transindirection;\r\n }\r\n\r\n let defaultTransInOptions: TransitionElementOptions = {duration: transInDuration};\r\n let transIn = transitionElement('defaultIn', {duration: defaultTransInOptions.duration});\r\n \r\n if (Boolean(self.options['transin'])) {\r\n let transInName = self.options['transin'];\r\n\r\n if (transInName === 'fly') {\r\n transInName = `${transInName}In`;\r\n defaultTransInOptions.keyframes = flyTransitionKeyframes({\r\n trans: 'in',\r\n direction: transInDirection,\r\n height: self.divHeight,\r\n width: self.divWidth,\r\n });\r\n }\r\n\r\n transIn = transitionElement(transInName, defaultTransInOptions);\r\n }\r\n\r\n const showCurrentMedia = async () => {\r\n let $mediaId = getMediaId(self);\r\n let $media = document.getElementById($mediaId);\r\n const isCMS = xlr.config.platform === 'CMS';\r\n\r\n if (!$media) {\r\n $media = getNewMedia();\r\n }\r\n\r\n if ($media) {\r\n $media.style.setProperty('display', 'block');\r\n\r\n if (Boolean(self.options['transin'])) {\r\n $media.animate(transIn.keyframes, transIn.timing);\r\n }\r\n\r\n if (self.mediaType === 'image' && self.url !== null) {\r\n ($media as HTMLImageElement).style\r\n .setProperty(\r\n 'background-image',\r\n `url(${!isCMS ? self.url : await getDataBlob(self.url)}`\r\n );\r\n } else if (self.mediaType === 'video' && self.url !== null) {\r\n ($media as HTMLVideoElement).src = await preloadMediaBlob(self.url, self.mediaType);\r\n } else if (self.mediaType === 'audio' && self.url !== null) {\r\n ($media as HTMLAudioElement).src =\r\n isCMS ? await preloadMediaBlob(self.url, self.mediaType) : self.url;\r\n } else if ((self.render === 'html' || self.mediaType === 'webpage') &&\r\n self.iframe && self.checkIframeStatus\r\n ) {\r\n // Set state as false ( for now )\r\n self.ready = false;\r\n\r\n // Append iframe\r\n $media.innerHTML = '';\r\n $media.appendChild(self.iframe as Node);\r\n\r\n // On iframe load, set state as ready to play full preview\r\n // (self.iframe) && self.iframe.addEventListener('load', function(){\r\n // self.ready = true;\r\n // if (self.iframe) {\r\n // const iframeStyles = self.iframe.style.cssText;\r\n // self.iframe.style.cssText = iframeStyles?.concat('visibility: visible;');\r\n // }\r\n // });\r\n }\r\n\r\n self.emitter.emit('start', self);\r\n }\r\n };\r\n const getNewMedia = (): HTMLElement | null => {\r\n const $region = document.getElementById(`${self.region.containerName}`);\r\n // This function is for checking whether\r\n // the region still has to show a media item\r\n // when another region is not finished yet\r\n if (self.region.complete && !self.region.layout.allEnded) {\r\n // Add currentMedia to the region\r\n\r\n ($region) && $region.insertBefore(self.html as Node, $region.lastElementChild);\r\n\r\n return self.html as HTMLElement;\r\n }\r\n\r\n return null;\r\n };\r\n\r\n showCurrentMedia();\r\n };\r\n\r\n mediaObject.stop = async function() {\r\n const self = mediaObject;\r\n const $media = document.getElementById(getMediaId(self));\r\n\r\n if ($media) {\r\n $media.style.display = 'none';\r\n $media.remove();\r\n }\r\n };\r\n\r\n mediaObject.init();\r\n\r\n return mediaObject;\r\n}","/*\n * Copyright (C) 2024 Xibo Signage Ltd\n *\n * Xibo - Digital Signage - https://www.xibosignage.com\n *\n * This file is part of Xibo.\n *\n * Xibo is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Lesser General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * any later version.\n *\n * Xibo is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * along with Xibo. If not, see <http://www.gnu.org/licenses/>.\n */\nimport { IMedia } from '../../Types/Media';\nimport { capitalizeStr, getMediaId } from '../Generators';\n\nexport default function VideoMedia(media: IMedia) {\n const videoMediaObject = {\n init() {\n const $videoMedia = document.getElementById(getMediaId(media)) as HTMLVideoElement;\n\n if ($videoMedia) {\n $videoMedia.onloadstart = () => {\n console.debug(`${capitalizeStr(media.mediaType)} for media > ${media.id} has started loading data . . .`);\n };\n $videoMedia.onloadeddata = () => {\n if ($videoMedia.readyState >= 2) {\n console.debug(`${capitalizeStr(media.mediaType)} data for media > ${media.id} has been fully loaded . . .`);\n }\n };\n $videoMedia.oncanplay = () => {\n console.debug(`${capitalizeStr(media.mediaType)} for media > ${media.id} can be played . . .`);\n \n const videoPlayPromise = $videoMedia.play();\n \n if (videoPlayPromise !== undefined) {\n videoPlayPromise.then(() => {\n console.debug('autoplay started . . .');\n // Autoplay restarted\n }).catch(error => {\n $videoMedia.muted = true;\n $videoMedia.play();\n });\n }\n };\n $videoMedia.onplaying = () => {\n console.debug(`${capitalizeStr(media.mediaType)} for media > ${media.id} is now playing . . .`);\n };\n\n if (media.duration === 0) {\n $videoMedia.ondurationchange = () => {\n console.debug('Showing Media ' + media.id + ' for ' + $videoMedia.duration + 's of Region ' + media.region.regionId);\n };\n $videoMedia.onended = () => {\n console.debug(`${capitalizeStr(media.mediaType)} for media > ${media.id} has ended playing . . .`);\n media.emitter?.emit('end', media);\n };\n }\n }\n }\n }\n\n return videoMediaObject;\n}\n","/*\n * Copyright (C) 2024 Xibo Signage Ltd\n *\n * Xibo - Digital Signage - https://www.xibosignage.com\n *\n * This file is part of Xibo.\n *\n * Xibo is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Lesser General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * any later version.\n *\n * Xibo is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * along with Xibo. If not, see <http://www.gnu.org/licenses/>.\n */\nimport { IMedia } from '../../Types/Media';\nimport { capitalizeStr, getMediaId } from '../Generators';\n\nimport './media.css';\n\nexport default function AudioMedia(media: IMedia) {\n const audioMediaObject = {\n init() {\n const $audioMedia = document.getElementById(getMediaId(media)) as HTMLAudioElement;\n let $playBtn: HTMLButtonElement | null = null;\n\n if ($audioMedia) {\n $audioMedia.onloadstart = () => {\n console.debug(`${capitalizeStr(media.mediaType)} for media > ${media.id} has started loading data . . .`);\n };\n $audioMedia.onloadeddata = () => {\n if ($audioMedia.readyState >= 2) {\n console.debug(`${capitalizeStr(media.mediaType)} data for media > ${media.id} has been fully loaded . . .`);\n }\n };\n $audioMedia.oncanplay = () => {\n console.debug(`${capitalizeStr(media.mediaType)} for media > ${media.id} can be played . . .`);\n };\n $audioMedia.onplaying = () => {\n console.debug(`${capitalizeStr(media.mediaType)} for media > ${media.id} is now playing . . .`);\n\n if ($playBtn !== null) {\n $playBtn.remove();\n }\n };\n\n const audioPlayPromise = $audioMedia.play();\n \n if (audioPlayPromise !== undefined) {\n audioPlayPromise.then(() => {\n console.debug('autoplay started . . .');\n // Autoplay restarted\n }).catch(error => {\n if (error.name === 'NotAllowedError') {\n // Let's show a play audio button\n $playBtn = document.createElement('button');\n\n $playBtn.classList.add('play-audio-btn');\n $playBtn.textContent = 'Play Audio';\n $playBtn.addEventListener('click', () => {\n $audioMedia.muted = false;\n $audioMedia.play();\n });\n $audioMedia.parentNode?.insertBefore($playBtn, $audioMedia.nextSibling);\n }\n });\n }\n if (media.duration === 0) {\n $audioMedia.ondurationchange = () => {\n console.debug('Showing Media ' + media.id + ' for ' + $audioMedia.duration + 's of Region ' + media.region.regionId);\n };\n $audioMedia.onended = () => {\n console.debug(`${capitalizeStr(media.mediaType)} for media > ${media.id} has ended playing . . .`);\n media.emitter?.emit('end', media);\n };\n }\n }\n },\n };\n\n return audioMediaObject;\n}\n","/*\r\n * Copyright (C) 2024 Xibo Signage Ltd\r\n *\r\n * Xibo - Digital Signage - https://www.xibosignage.com\r\n *\r\n * This file is part of Xibo.\r\n *\r\n * Xibo is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Lesser General Public License as published by\r\n * the Free Software Foundation, either version 3 of the License, or\r\n * any later version.\r\n *\r\n * Xibo is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Lesser General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Lesser General Public License\r\n * along with Xibo. If not, see <http://www.gnu.org/licenses/>.\r\n */\r\nimport {createNanoEvents} from 'nanoevents';\r\nimport {\r\n GetLayoutParamType,\r\n GetLayoutType,\r\n ILayout,\r\n initialLayout,\r\n OptionsType,\r\n} from '../../Types/Layout';\r\nimport { IXlr } from '../../Types/XLR';\r\nimport { nextId } from '../Generators';\r\nimport { Region } from '../Region';\r\n\r\nimport './layout.css';\r\nimport {composeBgUrlByPlatform, getIndexByLayoutId} from '../Generators/Generators';\r\n\r\nconst playAgainClickHandle = function(ev: { preventDefault: () => void; }) {\r\n ev.preventDefault();\r\n history.go(0);\r\n};\r\n\r\nexport function initRenderingDOM(targetContainer: Element | null) {\r\n let _targetContainer = targetContainer;\r\n const previewPlayer = document.createElement('div');\r\n const previewScreen = document.createElement('div');\r\n const endPlay = document.createElement('div');\r\n const playAgainLink = document.createElement('a');\r\n\r\n // Preview player\r\n previewPlayer.className = 'player-preview';\r\n previewPlayer.id = 'player_container';\r\n\r\n // Preview screen\r\n previewScreen.className = 'screen-preview';\r\n previewScreen.id = 'screen_container';\r\n\r\n // Ended play\r\n endPlay.className = 'preview-ended';\r\n endPlay.id = 'play_ended';\r\n endPlay.style.display = 'none';\r\n\r\n // Play again link\r\n playAgainLink.id = 'play_back_preview';\r\n playAgainLink.className = 'play-back-preview';\r\n playAgainLink.style.cssText = 'text-decoration: none; color: #ffffff;';\r\n playAgainLink.innerHTML = 'Play again?';\r\n playAgainLink.removeEventListener('click', playAgainClickHandle);\r\n playAgainLink.addEventListener('click', playAgainClickHandle);\r\n\r\n if (!_targetContainer) {\r\n _targetContainer = document.body;\r\n }\r\n\r\n if (_targetContainer) {\r\n if (_targetContainer.querySelector('#player_container') === null) {\r\n _targetContainer.insertBefore(previewPlayer, _targetContainer.firstChild);\r\n\r\n if (previewPlayer.querySelector('#screen_container') === null) {\r\n previewPlayer.appendChild(previewScreen);\r\n }\r\n\r\n if (previewPlayer.querySelector('#play_ended') === null) {\r\n previewPlayer.appendChild(endPlay);\r\n\r\n if (endPlay.querySelector('a') === null) {\r\n endPlay.appendChild(playAgainLink);\r\n }\r\n }\r\n }\r\n }\r\n}\r\n\r\nexport async function getXlf(layoutOptions: OptionsType) {\r\n let apiHost = window.location.origin;\r\n\r\n let xlfUrl = apiHost + layoutOptions.xlfUrl;\r\n let fetchOptions: RequestInit = {};\r\n\r\n if (layoutOptions.platform === 'CMS') {\r\n xlfUrl = apiHost + layoutOptions.xlfUrl;\r\n fetchOptions.mode = 'no-cors';\r\n } else if (layoutOptions.platform === 'chromeOS') {\r\n xlfUrl = layoutOptions.xlfUrl;\r\n fetchOptions.mode = 'cors';\r\n fetchOptions.headers = {\r\n 'Content-Type': 'text/xml',\r\n };\r\n } else if (layoutOptions.platform !== 'CMS' && layoutOptions.appHost !== null) {\r\n xlfUrl = layoutOptions.appHost + layoutOptions.xlfUrl;\r\n }\r\n\r\n const res = await fetch(xlfUrl);\r\n\r\n return await res.text();\r\n}\r\n\r\nexport function handleAxiosError(error: any, message?: string) {\r\n console.error(error);\r\n if (error.response.status == 500) {\r\n // SOAP responses are always 500's\r\n // Return the body\r\n throw new Error(error.response.data);\r\n } else {\r\n throw new Error(message || 'Unknown Error');\r\n }\r\n}\r\n\r\nexport function getLayout(params: GetLayoutParamType): GetLayoutType {\r\n let _currentLayout = undefined;\r\n let _nextLayout = undefined;\r\n let {\r\n inputLayouts,\r\n currentLayout,\r\n nextLayout,\r\n currentLayoutIndex: currLayoutIndx\r\n } = params.xlr;\r\n const hasLayout = inputLayouts.length > 0;\r\n let currentLayoutIndex = currLayoutIndx;\r\n let nextLayoutIndex = currentLayoutIndex + 1;\r\n\r\n if (currentLayout === undefined && nextLayout === undefined) {\r\n let activeLayout;\r\n // Preview just got started\r\n if (hasLayout) {\r\n let nextLayoutTemp = {...initialLayout};\r\n activeLayout = inputLayouts[currentLayoutIndex];\r\n _currentLayout = {...initialLayout, ...activeLayout};\r\n\r\n if (inputLayouts.length > 1) {\r\n nextLayoutTemp = {...nextLayoutTemp, ...inputLayouts[nextLayoutIndex]};\r\n _nextLayout = nextLayoutTemp;\r\n } else {\r\n _nextLayout = _currentLayout;\r\n }\r\n\r\n _currentLayout.id = activeLayout.layoutId;\r\n\r\n if (nextLayoutTemp) {\r\n _nextLayout.id = nextLayoutTemp.layoutId;\r\n }\r\n }\r\n } else {\r\n if (hasLayout) {\r\n _currentLayout = nextLayout;\r\n\r\n currentLayoutIndex = getIndexByLayoutId(inputLayouts, _currentLayout?.layoutId).index as number;\r\n nextLayoutIndex = currentLayoutIndex + 1;\r\n\r\n if (inputLayouts.length > 1 && nextLayoutIndex < inputLayouts.length) {\r\n if (Boolean(params.xlr.layouts[nextLayoutIndex])) {\r\n _nextLayout = params.xlr.layouts[nextLayoutIndex];\r\n } else {\r\n _nextLayout = {...initialLayout, ...inputLayouts[nextLayoutIndex]};\r\n }\r\n }\r\n\r\n // If _nextLayout is undefined, then we go back to first layout\r\n if (_nextLayout === undefined) {\r\n _nextLayout = params.xlr.layouts[0];\r\n }\r\n }\r\n }\r\n\r\n return {\r\n currentLayoutIndex,\r\n inputLayouts: params.xlr.inputLayouts,\r\n current: _currentLayout,\r\n next: _nextLayout,\r\n }\r\n}\r\n\r\nexport interface ILayoutEvents {\r\n start: (layout: ILayout) => void;\r\n end: (layout: ILayout) => void;\r\n}\r\n\r\nexport default function Layout(\r\n data: Document | null,\r\n options: OptionsType,\r\n xlr: IXlr,\r\n layout?: ILayout\r\n) {\r\n const props = {\r\n data: data,\r\n options: options,\r\n layout: layout || initialLayout,\r\n }\r\n const emitter = createNanoEvents<ILayoutEvents>();\r\n\r\n emitter.on('start', (layout: ILayout) => {\r\n layout.done = false;\r\n console.debug('Layout start emitted > Layout ID > ', layout.id);\r\n });\r\n\r\n emitter.on('end', async (layout: ILayout) => {\r\n console.debug('Ending layout with ID of > ', layout.layoutId);\r\n /* Remove layout that has ended */\r\n const $layout = document.getElementById(layout.containerName);\r\n\r\n layout.done = true;\r\n console.debug({$layout});\r\n\r\n if ($layout !== null) {\r\n $layout.remove();\r\n }\r\n\r\n if (xlr.config.platform !== 'CMS') {\r\n // Transition next layout to current layout and prepare next layout if exist\r\n xlr.prepareLayouts().then((parent) => {\r\n xlr.playSchedules(parent);\r\n });\r\n }\r\n });\r\n\r\n const layoutObject: ILayout = {\r\n ...props.layout,\r\n options: props.options,\r\n };\r\n\r\n layoutObject.on = function<E extends keyof ILayoutEvents>(event: E, callback: ILayoutEvents[E]) {\r\n return emitter.on(event, callback);\r\n };\r\n layoutObject.emitter = emitter;\r\n\r\n layoutObject.run = function() {\r\n const layout = layoutObject;\r\n const $layoutContainer = document.getElementById(`${layout.containerName}`);\r\n const $splashScreen = document.getElementById(`splash_${layout.id}`);\r\n\r\n if ($layoutContainer) {\r\n $layoutContainer.style.display = 'block';\r\n }\r\n\r\n if ($splashScreen) {\r\n $splashScreen.style.display = 'none';\r\n }\r\n\r\n console.debug('Layout running > Layout ID > ', layout.id);\r\n console.debug('Layout Regions > ', layout.regions);\r\n for (let i = 0; i < layout.regions.length; i++) {\r\n // playLog(4, \"debug\", \"Running region \" + self.regions[i].id, false);\r\n layout.regions[i].run();\r\n }\r\n };\r\n\r\n layoutObject.prepareLayout = function(){\r\n layoutObject.parseXlf();\r\n };\r\n\r\n layoutObject.parseXlf = function() {\r\n const layout = this;\r\n const {options} = layout;\r\n\r\n layout.done = false;\r\n layout.allEnded = false;\r\n layout.allExpired = false;\r\n layout.containerName = \"L\" + layout.id + \"-\" + nextId(options);\r\n layout.regions = [];\r\n\r\n /* Create a hidden div to show the layout in */\r\n let $layout = document.getElementById(layout.containerName);\r\n\r\n if ($layout === null) {\r\n $layout = document.createElement('div');\r\n $layout.id = layout.containerName;\r\n }\r\n\r\n let $screen = document.getElementById('screen_container');\r\n ($screen) && $screen.appendChild($layout);\r\n\r\n if ($layout) {\r\n $layout.style.display = 'none';\r\n if (xlr.config.platform === 'CMS') {\r\n $layout.style.outline = 'red solid thin';\r\n }\r\n }\r\n\r\n layout.layoutNode = props.data;\r\n\r\n /* Calculate the screen size */\r\n layout.sw = $screen?.offsetWidth || 0;\r\n layout.sh = $screen?.offsetHeight || 0;\r\n\r\n layout.xw = Number(layout.layoutNode?.firstElementChild?.getAttribute('width'));\r\n layout.xh = Number(layout.layoutNode?.firstElementChild?.getAttribute('height'));\r\n layout.zIndex = Number(layout.layoutNode?.firstElementChild?.getAttribute('zindex')) || 0;\r\n\r\n /* Calculate Scale Factor */\r\n layout.scaleFactor = Math.min((layout.sw / layout.xw), (layout.sh / layout.xh));\r\n layout.sWidth = layout.xw * layout.scaleFactor;\r\n layout.sHeight = layout.xh * layout.scaleFactor;\r\n layout.offsetX = Math.abs(layout.sw - layout.sWidth) / 2;\r\n layout.offsetY = Math.abs(layout.sh - layout.sHeight) / 2;\r\n\r\n /* Scale the Layout Container */\r\n if ($layout) {\r\n $layout.style.width = `${layout.sWidth}px`;\r\n $layout.style.height = `${layout.sHeight}px`;\r\n $layout.style.position = 'absolute';\r\n $layout.style.left = `${layout.offsetX}px`;\r\n $layout.style.top = `${layout.offsetY}px`;\r\n }\r\n\r\n if ($layout && layout.zIndex !== null) {\r\n $layout.style.zIndex = `${layout.zIndex}`;\r\n }\r\n\r\n /* Set the layout background */\r\n layout.bgColor = layout.layoutNode?.firstElementChild?.getAttribute('bgcolor') || '';\r\n layout.bgImage = layout.layoutNode?.firstElementChild?.getAttribute('background') || '';\r\n\r\n if (!(layout.bgImage === \"\" || typeof layout.bgImage === 'undefined')) {\r\n /* Extract the image ID from the filename */\r\n layout.bgId = layout.bgImage.substring(0, layout.bgImage.indexOf('.'));\r\n\r\n const bgImageUrl = composeBgUrlByPlatform(\r\n xlr.config.platform,\r\n {\r\n ...options,\r\n layout,\r\n }\r\n );\r\n\r\n if ($layout) {\r\n $layout.style.backgroundImage = `url(\"${bgImageUrl}\")`;\r\n $layout.style.backgroundRepeat = 'no-repeat';\r\n $layout.style.backgroundSize = `${layout.sWidth}px ${layout.sHeight}px`;\r\n $layout.style.backgroundPosition = '0px 0px';\r\n }\r\n }\r\n\r\n // Set the background color\r\n if ($layout && layout.bgColor) {\r\n $layout.style.backgroundColor = `${layout.bgColor}`;\r\n }\r\n\r\n // Hide if layout is not the currentLayout\r\n if ($layout && xlr.currentLayoutId !== undefined && xlr.currentLayoutId !== layout.id) {\r\n $layout.style.display = 'none';\r\n }\r\n\r\n // Create regions\r\n const layoutRegions = Array.from(layout?.layoutNode?.getElementsByTagName('region') || []);\r\n\r\n Array.from(layoutRegions).forEach((regionXml, indx) => {\r\n const regionObj = Region(\r\n layout,\r\n regionXml,\r\n regionXml?.getAttribute('id') || '',\r\n options,\r\n xlr,\r\n );\r\n\r\n regionObj.index = indx;\r\n layout.regions.push(regionObj);\r\n });\r\n };\r\n\r\n layoutObject.regionExpired = function() {\r\n const self = layoutObject;\r\n self.allExpired = true;\r\n\r\n for (let layoutRegion of self.regions) {\r\n if (!layoutRegion.complete) {\r\n self.allExpired = false;\r\n }\r\n }\r\n\r\n if (self.allExpired) {\r\n self.end();\r\n }\r\n };\r\n\r\n layoutObject.regionEnded = function() {\r\n const self = layoutObject;\r\n self.allEnded = true;\r\n \r\n for (var i = 0; i < self.regions.length; i++) {\r\n if (! self.regions[i].ended) {\r\n self.allEnded = false;\r\n }\r\n }\r\n \r\n if (self.allEnded) {\r\n self.stopAllMedia().then(async () => {\r\n console.debug('starting to end layout . . .');\r\n if (xlr.config.platform === 'CMS') {\r\n const $end = document.getElementById('play_ended');\r\n const $preview = document.getElementById('screen_container');\r\n \r\n if ($preview) {\r\n while($preview.firstChild) {\r\n $preview.removeChild($preview.firstChild);\r\n }\r\n \r\n $preview.style.display = 'none';\r\n }\r\n \r\n if ($end) {\r\n $end.style.display = 'block';\r\n }\r\n }\r\n \r\n self.emitter.emit('end', self);\r\n });\r\n\r\n }\r\n };\r\n\r\n layoutObject.end = function() {\r\n console.debug('Executing Layout::end and Calling Region::end ', layoutObject);\r\n\r\n /* Ask the layout to gracefully stop running now */\r\n for (let layoutRegion of layoutObject.regions) {\r\n layoutRegion.end();\r\n }\r\n };\r\n\r\n layoutObject.stopAllMedia = function() {\r\n console.debug('Stopping all media . . .');\r\n return new Promise(async (resolve) => {\r\n for(var i = 0;i < layoutObject.regions.length;i++) {\r\n var region = layoutObject.regions[i];\r\n for(var j = 0;j < region.mediaObjects.length;j++) {\r\n var media = region.mediaObjects[j];\r\n await media.stop();\r\n }\r\n }\r\n\r\n resolve();\r\n });\r\n };\r\n\r\n layoutObject.prepareLayout();\r\n\r\n return layoutObject;\r\n}\r\n","/*\r\n * Copyright (C) 2024 Xibo Signage Ltd\r\n *\r\n * Xibo - Digital Signage - https://www.xibosignage.com\r\n *\r\n * This file is part of Xibo.\r\n *\r\n * Xibo is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Lesser General Public License as published by\r\n * the Free Software Foundation, either version 3 of the License, or\r\n * any later version.\r\n *\r\n * Xibo is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Lesser General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Lesser General Public License\r\n * along with Xibo. If not, see <http://www.gnu.org/licenses/>.\r\n */\r\nimport {ILayout, InputLayoutType, OptionsType} from '../Layout';\r\nimport {platform} from '../../Modules/Platform';\r\n\r\nexport type PrepareLayoutsType = {\r\n moveNext?: boolean;\r\n};\r\n\r\nexport enum ELayoutType {\r\n CURRENT,\r\n NEXT,\r\n}\r\n\r\nexport interface IXlr {\r\n inputLayouts: InputLayoutType[],\r\n config: OptionsType,\r\n layouts: ILayout[],\r\n currentLayoutIndex: number;\r\n currentLayoutId: number | null;\r\n currentLayout: ILayout | undefined;\r\n nextLayout: ILayout | undefined;\r\n bootstrap(): void;\r\n init(): Promise<IXlr>;\r\n playSchedules(xlr: IXlr): void;\r\n prepareLayoutXlf(inputLayout: ILayout | undefined): Promise<ILayout>;\r\n prepareLayouts(): Promise<IXlr>;\r\n updateLayouts(inputLayouts: InputLayoutType[]): void;\r\n updateLoop(inputLayouts: InputLayoutType[]): void;\r\n}\r\n\r\nexport const initialXlr: IXlr = {\r\n inputLayouts: [],\r\n config: platform,\r\n layouts: [],\r\n currentLayoutIndex: 0,\r\n currentLayoutId: null,\r\n currentLayout: undefined,\r\n nextLayout: undefined,\r\n bootstrap() {\r\n },\r\n init() {\r\n return Promise.resolve(<IXlr>{});\r\n },\r\n playSchedules() {\r\n },\r\n prepareLayoutXlf(inputLayout: ILayout | undefined): Promise<ILayout> {\r\n return Promise.resolve(<ILayout>{});\r\n },\r\n prepareLayouts(): Promise<IXlr> {\r\n return Promise.resolve(<IXlr>{});\r\n },\r\n updateLayouts(inputLayouts: InputLayoutType[]) {\r\n },\r\n updateLoop(inputLayouts: InputLayoutType[]) {\r\n }\r\n};\r\n","/*\r\n * Copyright (C) 2024 Xibo Signage Ltd\r\n *\r\n * Xibo - Digital Signage - https://www.xibosignage.com\r\n *\r\n * This file is part of Xibo.\r\n *\r\n * Xibo is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Lesser General Public License as published by\r\n * the Free Software Foundation, either version 3 of the License, or\r\n * any later version.\r\n *\r\n * Xibo is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Lesser General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Lesser General Public License\r\n * along with Xibo. If not, see <http://www.gnu.org/licenses/>.\r\n */\r\nimport { createNanoEvents } from 'nanoevents';\r\nimport { ILayout, OptionsType } from '../../Types/Layout';\r\nimport { initialRegion, IRegion, IRegionEvents } from '../../Types/Region';\r\nimport { IMedia } from '../../Types/Media';\r\nimport { getMediaId, nextId } from '../Generators';\r\nimport { platform } from '../Platform';\r\nimport { Media } from '../Media';\r\nimport {\r\n TransitionElementOptions,\r\n TransitionNameType,\r\n compassPoints,\r\n flyTransitionKeyframes,\r\n transitionElement,\r\n} from '../Transitions';\r\nimport {IXlr} from '../../Types/XLR';\r\n\r\nexport default function Region(\r\n layout: ILayout,\r\n xml: Element,\r\n regionId: string,\r\n options: OptionsType,\r\n xlr: IXlr,\r\n) {\r\n const props = {\r\n layout: layout,\r\n xml: xml,\r\n regionId: regionId,\r\n options: options,\r\n }\r\n const emitter = createNanoEvents<IRegionEvents>();\r\n let regionObject: IRegion = {\r\n ...initialRegion,\r\n ...props,\r\n };\r\n\r\n regionObject.prepareRegion = function() {\r\n const self = regionObject;\r\n const {layout, options} = self;\r\n self.complete = false;\r\n self.ending = false;\r\n self.ended = false;\r\n self.id = props.regionId;\r\n self.options = {...platform, ...props.options};\r\n self.containerName = `R-${self.id}-${nextId(self.options as OptionsType & IRegion[\"options\"])}`;\r\n self.xml = props.xml;\r\n self.mediaObjects = [];\r\n\r\n self.sWidth = (self.xml) && Number(self.xml?.getAttribute('width')) * layout.scaleFactor;\r\n self.sHeight = (self.xml) && Number(self.xml?.getAttribute('height')) * layout.scaleFactor;\r\n self.offsetX = (self.xml) && Number(self.xml?.getAttribute('left')) * layout.scaleFactor;\r\n self.offsetY = (self.xml) && Number(self.xml?.getAttribute('top')) * layout.scaleFactor;\r\n self.zIndex = (self.xml) && Number(self.xml?.getAttribute('zindex'));\r\n \r\n const regionOptions = self.xml?.getElementsByTagName('options');\r\n\r\n if (regionOptions) {\r\n for (let _options of Array.from(regionOptions)) {\r\n // Get options\r\n const _regionOptions = _options.children;\r\n for (let regionOption of Array.from(_regionOptions)) {\r\n self.options[regionOption.nodeName.toLowerCase()] = regionOption.textContent;\r\n }\r\n }\r\n }\r\n\r\n\r\n let $region = document.getElementById(self.containerName);\r\n const $layout = document.getElementById(`${self.layout.containerName}`);\r\n\r\n if ($region === null) {\r\n $region = document.createElement('div');\r\n $region.id = self.containerName;\r\n }\r\n\r\n ($layout) && $layout.appendChild($region);\r\n\r\n /* Scale the Layout Container */\r\n /* Add region styles */\r\n $region.style.cssText = `\r\n width: ${self.sWidth}px;\r\n height: ${self.sHeight}px;\r\n position: absolute;\r\n left: ${self.offsetX}px;\r\n top: ${self.offsetY}px;\r\n z-index: ${Math.round(self.zIndex)};\r\n `;\r\n $region.className = 'region--item';\r\n\r\n /* Parse region media objects */\r\n const regionMediaItems = Array.from(self.xml.getElementsByTagName('media'));\r\n self.totalMediaObjects = regionMediaItems.length;\r\n\r\n Array.from(regionMediaItems).forEach((mediaXml, indx) => {\r\n const mediaObj = Media(\r\n self,\r\n mediaXml?.getAttribute('id') || '',\r\n mediaXml,\r\n options as OptionsType & IRegion[\"options\"],\r\n xlr,\r\n );\r\n\r\n mediaObj.index = indx;\r\n self.mediaObjects.push(mediaObj);\r\n });\r\n\r\n self.prepareMediaObjects();\r\n };\r\n\r\n regionObject.finished = function() {\r\n const self = regionObject;\r\n console.debug('Region::finished called . . . ', self.id);\r\n // Mark as complete\r\n self.complete = true;\r\n self.layout.regions[regionObject.index] = regionObject;\r\n self.layout.regionExpired();\r\n };\r\n\r\n regionObject.prepareMediaObjects = function() {\r\n const self = regionObject;\r\n let nextMediaIndex;\r\n\r\n if (self.mediaObjects.length > 0) {\r\n\r\n if (self.curMedia) {\r\n self.oldMedia = self.curMedia;\r\n } else {\r\n self.oldMedia = undefined;\r\n }\r\n\r\n if (self.currentMediaIndex >= self.mediaObjects.length) {\r\n self.currentMediaIndex = 0;\r\n }\r\n\r\n self.curMedia = self.mediaObjects[self.currentMediaIndex];\r\n\r\n nextMediaIndex = self.currentMediaIndex + 1;\r\n\r\n if (nextMediaIndex >= self.mediaObjects.length ||\r\n (\r\n !Boolean(self.mediaObjects[nextMediaIndex]) &&\r\n self.mediaObjects.length === 1\r\n )\r\n ) {\r\n nextMediaIndex = 0;\r\n }\r\n\r\n if (Boolean(self.mediaObjects[nextMediaIndex])) {\r\n self.nxtMedia = self.mediaObjects[nextMediaIndex];\r\n }\r\n\r\n const $region = document.getElementById(`${self.containerName}`);\r\n // Append available media to region DOM\r\n if (self.curMedia) {\r\n ($region) && $region.insertBefore(self.curMedia.html as Node, $region.lastElementChild);\r\n }\r\n\r\n if (self.nxtMedia) {\r\n ($region) && $region.insertBefore(self.nxtMedia.html as Node, $region.lastElementChild);\r\n }\r\n }\r\n };\r\n\r\n regionObject.run = function() {\r\n console.debug('Called Region::run > ', regionObject.id);\r\n\r\n // Reset region states\r\n regionObject.reset();\r\n\r\n if (regionObject.curMedia) {\r\n regionObject.transitionNodes(regionObject.oldMedia, regionObject.curMedia);\r\n }\r\n };\r\n\r\n regionObject.transitionNodes = function(oldMedia: IMedia | undefined, newMedia: IMedia | undefined) {\r\n const self = regionObject;\r\n let transOutDuration = 1;\r\n let transOutDirection: compassPoints = 'E';\r\n\r\n if (newMedia) {\r\n if (oldMedia && Boolean(oldMedia.options['transoutduration'])) {\r\n transOutDuration = Number(oldMedia.options.transoutduration);\r\n }\r\n\r\n if (oldMedia && Boolean(oldMedia.options['transoutdirection'])) {\r\n transOutDirection = oldMedia.options.transoutdirection;\r\n }\r\n \r\n let defaultTransOutOptions: TransitionElementOptions = {duration: transOutDuration};\r\n let transOut = transitionElement('defaultOut', {duration: defaultTransOutOptions.duration});\r\n \r\n let transOutName: TransitionNameType | string;\r\n if (oldMedia && Boolean(oldMedia.options['transout'])) {\r\n transOutName = oldMedia.options['transout'];\r\n \r\n if (transOutName === 'fly') {\r\n transOutName = `${transOutName}Out`;\r\n defaultTransOutOptions.keyframes = flyTransitionKeyframes({\r\n trans: 'out',\r\n direction: transOutDirection,\r\n height: oldMedia.divHeight,\r\n width: oldMedia.divWidth,\r\n });\r\n }\r\n \r\n transOut = transitionElement(transOutName as TransitionNameType, defaultTransOutOptions);\r\n }\r\n \r\n const hideOldMedia = new Promise((resolve) => {\r\n // Hide oldMedia\r\n if (oldMedia) {\r\n const $oldMedia = document.getElementById(getMediaId(oldMedia));\r\n if ($oldMedia) {\r\n const removeOldMedia = () => {\r\n $oldMedia.style.setProperty('display', 'none');\r\n $oldMedia.remove();\r\n };\r\n\r\n let oldMediaAnimate: any;\r\n if (Boolean(oldMedia.options['transout'])) {\r\n oldMediaAnimate = $oldMedia.animate(transOut.keyframes, transOut.timing);\r\n }\r\n\r\n if (Boolean(oldMedia.options['transout']) && self.totalMediaObjects > 1) {\r\n if (transOutName === 'flyOut') {\r\n // Reset last item to original position and state\r\n oldMediaAnimate ? oldMediaAnimate.finished\r\n .then(() => {\r\n resolve(true);\r\n oldMediaAnimate?.effect?.updateTiming({fill: 'none'});\r\n removeOldMedia();\r\n }) : undefined;\r\n } else {\r\n setTimeout(removeOldMedia, transOutDuration / 2);\r\n resolve(true);\r\n }\r\n } else {\r\n removeOldMedia();\r\n // Resolve this right away\r\n // As a result, the transition between two media object\r\n // seems like a cross-over\r\n resolve(true);\r\n\r\n }\r\n }\r\n }\r\n });\r\n \r\n if (oldMedia) {\r\n hideOldMedia.then((isDone) => {\r\n if (isDone) {\r\n newMedia.run();\r\n }\r\n });\r\n } else {\r\n newMedia.run();\r\n }\r\n }\r\n };\r\n\r\n regionObject.playNextMedia = function() {\r\n const self = regionObject;\r\n /* The current media has finished running */\r\n if (self.ended) {\r\n return;\r\n }\r\n\r\n if (self.currentMediaIndex === self.mediaObjects.length - 1) {\r\n self.finished();\r\n\r\n if (self.layout.allEnded) {\r\n return;\r\n }\r\n }\r\n\r\n // When the region has completed and when currentMedia is html\r\n // Then, preserve the currentMedia state\r\n if (self.complete &&\r\n self.curMedia?.render === 'html'\r\n ) {\r\n return;\r\n }\r\n\r\n // When the region has completed and mediaObjects.length = 1\r\n // and curMedia.loop = false, then put the media on\r\n // its current state\r\n if (self.complete && self.mediaObjects.length === 1 &&\r\n self.curMedia?.render !== 'html' &&\r\n self.curMedia?.mediaType === 'image' &&\r\n !self.curMedia?.loop\r\n ) {\r\n return;\r\n }\r\n\r\n self.currentMediaIndex = self.currentMediaIndex + 1;\r\n self.prepareMediaObjects();\r\n\r\n console.debug('region::playNextMedia', self);\r\n self.transitionNodes(self.oldMedia, self.curMedia);\r\n };\r\n \r\n regionObject.end = function() {\r\n const self = regionObject;\r\n self.ending = true;\r\n /* The Layout has finished running */\r\n /* Do any region exit transition then clean up */\r\n self.layout.regions[self.index] = self;\r\n\r\n console.debug('Calling Region::end ', self);\r\n self.exitTransition();\r\n };\r\n\r\n regionObject.exitTransition = function() {\r\n const self = regionObject;\r\n /* TODO: Actually implement region exit transitions */\r\n const $region = document.getElementById(`${self.containerName}`);\r\n\r\n if ($region) {\r\n $region.style.display = 'none';\r\n }\r\n\r\n console.debug('Called Region::exitTransition ', self.id);\r\n\r\n self.exitTransitionComplete();\r\n };\r\n\r\n regionObject.exitTransitionComplete = function() {\r\n const self = regionObject;\r\n console.debug('Called Region::exitTransitionComplete ', self.id);\r\n self.ended = true;\r\n self.layout.regions[self.index] = self;\r\n self.layout.regionEnded();\r\n };\r\n\r\n regionObject.reset = function() {\r\n regionObject.ended = false;\r\n regionObject.complete = false;\r\n regionObject.ending = false;\r\n console.debug('Resetting region states', regionObject);\r\n };\r\n\r\n regionObject.on = function<E extends keyof IRegionEvents>(event: E, callback: IRegionEvents[E]) {\r\n return emitter.on(event, callback);\r\n };\r\n\r\n regionObject.emitter = emitter;\r\n\r\n regionObject.prepareRegion();\r\n\r\n return regionObject;\r\n}","var img = \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA+gAAAJWCAYAAADLFK1VAAAACXBIWXMAACDOAAAgzgFjDuzcAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAIABJREFUeJzs3XeYXGXZx/HffWb7bgrJNkJLQqRIERSlC6gUFRXBkNCxgCKghnThlbUgpNAVpVgBKfFFRBFsiCigAlKklwQpybaEtG3ZnXO/fyyv7s7MJlvnzJn9fq7LS+Y5Z+b8JjM7M/dznvM8EgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwBZY1AEAAACQB6Z7Yvsd143t7Cwe6wVdFdYVlEhSMkisVWHXRi8qb2mqs41RxwTyUc0cL/eilgoLC8qDzuRWkuQFYbusoKVIHetee2Xcei2zZNQ5sWUU6AAAAOi/Og8mtbTuFZr2c7ddJN9Zsp0kbS8p2Ox9XRvd9KKZXjT5C6Hbv4KC5AP1F49pykp2IOYmzV5f2ZUoeL/cdjf5LjLtJNdOksZs4a4u6TXJX5Dbi2b+vJn+vmpF2eMU7rmFAh0AAACbNWl+2/bJpB8j02GSDpG01TA+vEv2tOT3mfx39evKfq/rrHMYHx+IrzovqGpp+VBgwZEKdZhMe2hLHWEDs1bSA5LuC0K7c9Wlpf8exsfGIFCgAwAAIM22s7y0q6DtaJdOlfRhSYksHfotyZaFgW5sWlTyoGSepeMCOaN2/obdPJk4RabTJNVm7cCmx+S6saCg66Y3Lx67OmvHxX9QoAMAAOA/Jp3Xul0yobmSPiOpPOI4T0m6pOHV0tsZhou8V+dBbUvbcTItdNfeEadpc9ePEm6LOaueXRToAAAAUNWC9mlBmFwgt1MkFfXnPhPKpB0rpalV0tSJpgnlUnmRNKZEKiuSOjql1k2utk7T2jbXm2ulFaul5aulV1dLnf0vuV+S7JKGdSU3MvwdeafOC2pb209y9wWSdunPXQoT0vYTpB0nSlMqpW3HS+NKTWWFrrIiU0mh1LJJ2tDe/f9vtUrLm6VXml3Lm6XVLf1O1+nym8Nk4uLmy0peHOxTRP9RoAMAAIxiNXO83K3taybNklS42X3HSAdOlfafatp/SndRMFibuqQn3pAeWuF6cHn3f2+5YPdnzYOz65eW3j/4IwO5o2pu28GBdI3ku29uv4JA2ntbaf+p0gFTTHtvJxUXDP64K9dJDy2XHn77769+/Rbv0mnSVV1W+vXmxbZh8EfGllCgAwAAjFI1c1o+JrOrJe3Q1z5jSqTDd5aO3ct04FTJRujX4/p26ddPu+54Qnrsdck3f+X5rwtMZ725uOyNkUkDjKxtZ62b0FlYeKFc52gzk769o1o6bi/Tp/aWKkfwgpOnV0r/+6T0iydca9s2s6NplbstaFxS+tORSzO6UaADAACMMhPO9bGFpW3Xy3V8X/tMniB94WDpmD27h8tm08tN0nUPun7x5GbPqr/l5p9pXFx+ZxajAUNWM7flaMl+LGlipu2FCenje0hnHijtXJPdcq2jS7rrX9L3/tI9FL4v5rqjvavjs2uv2Gpt9tKNDhToAAAAo8jWs1veE5rdKtO0TNt3qjadc4j00d2kxHAu5jQIK9dJ1z0o/exR16aujLu4pKsqy0vnPVNnm7KbDhigM72wdlzbxS6dpwx1WGFCmvke0+cPGtrlI8MhdOmeZ6Sr/yw939DncJYVZppZv7jsH9nMlu8o0AEAAEaJmjktZ7w9pL04dduYEmnWYaZT9+2+3jWXrFgtXXi364GX+9zlkaT5Mc2Ly1dmMRbQb1VzN9YGCn4hab9M2w+cKn3jo6Ydq7IcbAuSoXTTI65L/9h9GUoGm8x8Vv3i8muyHC1vUaADAACMAtVz2i4087pM2z66u/S1D5tqxmQ51ADd82x3od6YeYqqV5PJ4EhmmkauqZ7bvqMp/K2kHVO3VZZLF37E9LE9Igg2AE0bpW/d6/rlU33t4d9uWFJ2gWSbnz0CW0SBDgAAkNfcaua2XaruWdp7KS6Q5h8ufWb/+PwkXNMqnXeHdP+LGeuANe46unFp2cPZzgVkUjNnw+6yxL2Stkndtt8U6cpP5X7HWE+/eFK64FeulgwXlLj7Txoryj6nOst8QQr6JT6fxgAAABggt9q5rT922ampW95RLX33+O5rzuMmdOmaB6TL/+RKhikbXRsV6PCGxWV/iyQc8LatZ7e8JwyCP0o+rmd7IpDOPcR07iHRz/MwGK80SWff3ue16bc1lJeeqDpL/ctEP8XvExkAAAD9Ujuv9VJ3nZfavt8U6boTpLEl8f4p+IfnXecsk9o70zattjDx/vpLi5+NIBagqgXt04Jk+FdJNT3bCxPSFceZPrrZVc9zX+sm6Yu3Sfe/lF6km+z79UtKz4ogVl6I96cyAAAAMqqZ2/ZVyS9KbT9iV9NVn1LWl04bKU+8IZ1+Y8a1m98MQjtw1aWl/44gFkaxynktkxJuD0qa3LO9vEj63kzT+zOunxA/nUlp9h2uu/6Vvs1lFzYuKf1G9lPFHwU6AABAnqmZ0zpTpp8p5bfecXtJi4+xWA6r3Zzn6l0n/EgZinR7Wl6yX8NSa4kiF0afbWd5aWdB20OS9urZPrZEuuXTpt22jijYCAldOv9X0i2Ppp9Jd7NTGxeX3hhBrFjLs49nAACA0a1qQfs0mV+rlOL8gzubFuVhcS5Ju9aafnKqqbwodYvvLrVeHUUmjE6dhe1XKqU4Ly6Qbjgx/4pzSQpMuuhj0kd2S99m7t+rnd3xzuynirc8/IgGAAAYnSbXeUkiDG+XbGzP9r23la6ennvrmw+nd20jXXuCqTCRssHs07Xz2k6LJBRGldo5rcfL/YyebYlAuuJTpvdNjihUFgTWPRv9wWmLyKncg/D2SXVeFkGs2Mrjj2kAAIDRpbWlbam79u7Zts146cenmMrSzi7nn4N2lM4/Mr3d3b87aV77ztlPhNGiem77jm66IbV94RGmD4+Cc8iFCek7x0vbb5W6xXdLtrZfEUWmuKJABwAAyAO1s1vea1KvmZMLgu4zW+NKo0qVfafvl7EgKk96eK3kzL+EEWHmV0rqtaL5B3Y2fXb/iAJFYFyp6bszTEUFKRvcP1c7p+3QKDLFEQU6AABA3E33hBJ2rVJ+28073LTP9hFlitAln8h0Jk+H1MxpmxFBHOS56rmtx8n9oz3bth4nXXasZKOsS2iPSdKCw9OazU3f0ZmeJ2tHjCwKdAAAgJirmdz2xdSh7e/dXjrjgKgSRWtcqWnpJy29OAp02YRzfWzGOwGDUFXnFSZdntq+5BjT+FE0cqWnT+9n2n9KaqvvVj2+7UtR5IkbCnQAAIAYe7vg/HrPtsKE9M2Pjb6zdz29b7L0yT1TGl1bF5a0zo0iD/KTbWyfJWm7nm0f26N7PoTRykz65tHpEzaa+9e2X7A2fWwLeqFABwAAiLGi0razJPX60fvp/aRdakZxdf62rx5lGluS2hqcO/4rb42PIg/yS80cLzfzc3u2jSmRzj+Sv71pVdLn0kbw2Nj2ruJzosgTJxToAAAAMbXtLC9116yebeNLpS8dSoEgSZXl0jmHpP5b+LjiopKzMt4BGAAP2r4gqapn2xcPNtVyEYUk6dxDTBPLe7eZ+Zer6rwimkTxQIEOAAAQU12FbZ+VVNOz7dP7myqKIwqUg056r9KvBXafxdrMGIpp53qxSbN7to0tkU5+b1SJck9ZkfTZA9I6Cydaa9vno8gTFxToAAAAMeVuvX7oVhR3D2/Hf5UXSZ/ZP61IqOra2H5sFHmQHzaUtB0j19Y9207fr3uIO/7rlPcq7TITC/UFljzsGwU6AABADG09u+U9ku/es+3EfdJ/DEM6bV9XeVHvNrPw1GjSIE+c3PNGSWHGjqBRb0yJdOq+KY2madXz20bRCvEDQ4EOAAAQQ2HC0grMT+2daU+MKzUd9c7UVvvgNvNat40iD+KtZs6GaklH9mw7fJcMl1JAkjTj3elLHgahnZx5b1CgAwAAxE2dF8g1s2fTnttIO1VzBq8vx+6V9m8TJKUTosiCmLPECZIKezYd+66IssTAdltJ79mud5vLZ+xW50WZ7zG6UaADAADETPXGtvdKqu7ZRoGweftPkbYe17vNXR+OJg3izT/S89bEcungaXSObc4n0z+fJqzZ0M6MGRlQoAMAAMSMBXZoattR76RA2JzApCN2Sfs32n/bWc7AZPRb91lfO7Bn25G7mgqoqjbrqHemD3P3RPiBaNLkNt5KAAAAceO9f9hOrRRrL/fD/lPTmko6C9sPiCAKYqqxpX1fSb1W9z4g/X2FFBPLpZ1TLsEJZYdFFCenUaADAADEyLRzvViyXkXlAVM4e94f+0/uPpPeW0iRgH4z16G9bpu035SIwsRMakeGufabVOdl0aTJXRToAAAAMbK+uGVnSb1+1O5PgdAv40qlXWtTGj1g7nv0m5n3er9Mq5Iqy/vaGz3tN9lTm4rCDa27RZEll1GgAwAAxEhgwc6pbWlFJ/q0S01qi6f9ewJ981163to17f2Evuxamz7SJ0wEO0UQJadRoAMAAMSIy3oVlAVB9zJG6J8dq9KKhMmT67wkiiyImemekKzXQO2plVxe0l/bjJeKC3q3BQrpIEtBgQ4AABArvc/4bj9BKkxElSV+plamNSXa2zbuGEEUxEzVjh1TJBX3bNsx/f2EPgQmTZ7Yu0MjtcMRFOgAAABxs23PGztM4AzeQEyekHYdrJKhbRdBFMRMIvS098nkiVEkia+0vz8Xf3spKNABAABixKVeC6qNK0kvONG3cSXpHRoJBWMiiIKYcYVp75OxXBwxIONKU1uMv70UFOgAAAAxYlKvH7QVxZxBH4jy4vQODadIQD94ho6ciuJMe6Iv6Z9XPjbjjqMYBToAAECcmCp63iwr4gz6QJQXmSytT8Mp0NEP6WfQy4qiyBFf5emfV/ztpaBABwAAiBNXr0GiJYVRBYmnRCAVpU6qZ1aWcWegBwstbUB76qzk2LzSorTeMf72UlCgAwAAxImprefN9s6ogsRTMpQ6ulIaQ2+JJAxixeVtqW1p7yVsVuumtDPo/O2loEAHAACIEZM29Lzdsolr0AdiY0f6JQEW2IYMuwK9mIK090nLpiiSxFeGzyv+9lJQoAMAAMSIp/ygzVRwom+tGTs0nCIB/RCmvU82dkSRI742tqd+XtE5looCHQAAIE5c63veXNfGGfSBeKstvUMjtPTCC0iV6Qz6urRB79icde0pn1fu6zPvOXpRoAMAAMSIyV/veXvFas6gD8Srq9M7NAq6Cv8dQRTEjBfYa6ltK1ZHkSS+ljenfF4FSvs3He0o0AEAAGLEFbzQ8/Yba6VNTFTVb680pzV1bTWmaHkEURAzDSXFr0pq79mWVnCiT8lQeu2t3m0mfyHz3qMXBToAAECMeMoP2mQo/XtNVGniZ0VKQWWm5c/UGVN9YcvqLJTs5Z5Ny9M7fNCH1zN0JrobBXoKCnQAAIAYCYLk86ltz9ZHkSSenq3vPcTdXS9GFAUxlHrGl7+9/nsuw79VgjPoaSjQAQAAYqT+rYoX5drYs+3hFVGliZc1rdILjaln0P2xiOIghtys1/tlebNUzzRn/fJQ+oUk7UXlZc9GECWnUaADAADEyXXWaWZ/7dn08Aqug+2Ph5ZLnvJPZcngvmjSIJ78T6ktdJD1z0Ppn1MPvlpn7Zn2Hc0o0AEAAOLGvFdR+e813ZPFYfMyFFKt5ZtK/h5BFMRUQ1npo1LvpcEeWk4H2ZY0bJBeaUppdEvr7AAFOgAAQOxYhrN49zBQdLO6Qul3z6UWUv7Xl6+2jkgCIZ7qrEsW/KVn0++eZyWFLfnN0+mdGC5n9EoGFOgAAAAxs6qs7J+S3uzZdscTEYWJib+87GramNLodnckYRBrrvDXPW+va5Puf7mvvSFJv3gqramxsaL0kQii5DwKdAAAgLips9BdP+vZ9Fy969l6htr25Y4n05q6vCi8LYIoiLmizq7bJfUaeXHH4/zt9eXlJumpN9Oab1GdMe4gAwp0AACAGDIlf5radttjlmnXUe+tVun3qYvTmf228dsVDZEEQqy9cfm4NebqNfrijy9KjRuiSpTbbnssvfMiCP3GCKLEAgU6AABADDUsHfO0pF4D2299LMMwbuiGh1ztnb3bLPS0Dg6gv8Kgd4HZmex+n6G3dW3SLWkLGfpzqy4tZ3nDPlCgAwAAxJX7NT1vdnRJP3yYIqGndW2uG/+RNrJgZUVH6S+jyIP80Li27G5J/+7ZdvMj0tq2iALlqB887NqYMg2jSd+NJk08UKADAADEVGVF2U9ceqNn202PdJ+1Qrcf/920vj2t02Ips7djSK6zTpMv6dnUsokOsp7Wtbl+/Le05vqCrrIfRhAnNijQAQAAYuqZOttk0tKebRvapaV/jCpRblm1Trrur2kF0+qwvPT6KPIgv5SUl/1A0sqebdc9KL3+VkSBcsxl95nWt/duc+nSNy43uhA3gwIdAAAgxhLdxWZjz7abH3E9mT5r8qjz9d+4WjalttplTXXGlfoYslfrrN2ly3u2tXdKX78nqkS545lV0k2PpHeOeXnp96PIEycU6AAAADG2ss5aJVvYsy106fxfuZJhVKmid/+LrnufS2t+NVFeckUEcZCnyspLvyNXr1XQ//C863fPjd6h7qFLF2T4/HHzC+gc2zIKdAAAgJhrWFLyI7ke6tn29ErpqvtHZ5GwplVacFeGDe5f6u7QAIbHq3XW7hacndq+8C6pYZQuu/adP0uPv5HSaHqscUUZl5b0AwU6AABA7JkrEX5BUq/FxK7+s/SXVyKKFJHQpVk/l+rX9253s3salpb/KppUyGeNS0p+Z9L/9mxb3SJ9+eejbxTLP16VrkzvGAwV6mwts2QEkWKHAh0AACAPNCyq+Jdcl/Vs6y5WXY2j6EzeNQ9If345rUBYm0jqrCjyYHRImL4iaU3Ptr+tkK7+8+gZxbK6RTp3WcZOiSsblpb9PYJIsUSBDgAAkCcaKkovkPRgz7bmFunUn3YveZTvfvUv6bL70p+nmz676tLSf2e4CzAs3lxc9obJT5HU6w145f3SssejyZRNbZ3SGT/zTMP6H60sL10QQaTYokAHAADIF3XWlUjqBEmrezY/3+D6/K1SR1dEubLg4RXS7F+4wtT63HRV4+KyOyIJhVGlfkn5b8x6z+ruLn31LtefXszfDrLOpHTWrdI/X0/btFaJYMYzdZa2lgL6RoEOAACQR1ZeVva65KdL6nW9599WSF9e5urMw6tAH3+j++zdpvQOiL+PaSudF0EkjFL1a0sXpE7Y2JmUzr69+/rsfNOZlM67w3X/S+nXnbv5pxsuKVkeRa44o0AHAADIMw1Lyn/t7mkzS9/7nHTaja4N7VGkGhl/fUU65SeujR0pG1wve2H4iZevttQtwMi5zjoLCrs+LvmzPZtbN0kn/9R1z7N93TF+2jqlz9/afWlJBnMaF5ffmeVIecGiDgAAAICRUT2n7UIzr0tt332S9JNTTBPLIwg1jH7xpDTvzoyjAlZawg6sv6T01eynAqSJs1q3KSjQg5J26NmeCKRvHi2duE+8y7D17dJnbnI9+lqGjeYXNSwuvyDrofJEvN8ZAAAA2KyaOa1Xy3ROavs246XvHG/ae9soUg1NZ1Ja9HvXDx7uvsY3xRr38LDGpRVPRRAN+I/a2R3v9CB5v6Sq1G2n72f66hFSUUH2cw3VU29KZ9/uev2tDBvNrm9YXPJ5yfL3ovsRRoEOAACQ52rntc531yWp7QWBdM4h0pcONQUx+VW4ap10zu2ux9InpJJMqzwMj6I4R66oWdA+VV3hb2Walrptt62l784wTZ4QRbLB+dmjrgvvVua5LExXNZSVzlKdjbLV34dXTD6KAQAAMBQ1c1vPlXSFMsxB9P5p0tc/apoyMfu5+it06ZZHXYt+3z28Np0/m0jaUd2T5AG5o3Jey6SEB/dKvkfqtrElprkfcp24jymRw7OD/XuNdOFvpPszz0bvbprbuLjs0mznykcU6AAAAKNE7bzWT7nrh5LGpG4rKpDOOkg662BTSWEE4Tbj6ZXS+b9yPflmX3v4Hwq7uma8cfm4NdnMBfTX+K+8Nb6koORWNz8y0/bdJ0kXfcz0rm2ynWzzOrqk7/1F+t5fvK9lGlskndGwpOyW7CbLXxToAAAAo0jlee07JRLhbZL2yrR90jjprIOl499tKo74+tgXG13XPCD96mkpmXnQbNLdvt5YUXIRw2qR8+o8qGltny/3b0hK++sKTPro7tIXD5Z2rY22TNvUJd3+uOv7f5HeWNvXXvavwIIZqxYXP5fNbPmOAh0AAGCUmVznJe0t7Ze7/PPq4/dg9RjpcweYZrxbGlea3Xz/fF267q+u3z3fPbS9DyvN7aT6paX3Zy8ZMHRV89sOCkL/maTtMm03kz60s+nMg6R9tuu+nS3r26Vlj3f//TVs2NyedkNhV8mX3rjc2rKVbbSgQAcAABiltp7d9v4w0DWS79bXPoUJ6f3TTMftJR2+S/ftkVC/XrrzKen2f7qWN29219BcNycKu2a9efHY1SOTBhhZNXO83ILWue62UFJRX/tNGid9fA9p5j4jN5lcMpQeXiHd8UT3Ou1tnZvZ2fVyaOG5TUsq7h2ZNKBABwAAGM3O9MLa8W3nuet/JG12ZfSKYmnfyab9p0gHTJV2qdGgZ39f1+b6+6vSw6+aHlrePZw9w5Jpqf4WJv2LTZeVPz64owK5pXrOxj3NgmskHbilfXeqNh0wVdp/irTf5MGPbAldeqHB9fAK00MrpL+/6tqQceLFXlrl9u3KipIlz9TZpsEdGf1BgQ4AAABVzd1Ym1Aw211fkKmiP/cpKpCmTDRNneiaMlGqrDCVFbnGlpjKi10dnVJrp6mlw7Wu3fTmWml5c/cZ8s0Pn01hesxDXdRYUfpLrjVH/nGrmdN6tMzOl7Rvf+9VPUaaWilNnWjaZrw0rtRVXmQqL3IVF0otHab17a7WTabmja4Vq6UVq00rVvc54VsmLZKuS5ovbV5cvnIQTw4DRIEOAACA/9hm4fqJya7El1x2tqRIF15z0wPu4cUMp8VoUTOn/UOy8KuSDlW0tdoamX/PEuGV9RePaYowx6hDgQ4AAIA0u9V5UVNr60fM7VRJH5FUnKVDrzD5jUklbmpaUvJSlo4J5JTque07yv1kMz9F0o5ZOuwmSfe46adj20rvfvlq68jScdEDBToAAAA2a9tZ6yZsKiz6qIXhYTL7gKQdhvHhN7npbwrtPsl/17i09G+SbflqdGBUcKuZ17avux1h8sMk7a/h7Sx73d3vkwX3FRZ03s3Ei9GjQAcAAMCA1Cxon6ou38+CcBd320nSzpJPlWzsZu6WdGmVSS+a7EV3f0GB/StRVvLwyjprzVZ2IM62neWlnYn2/SXf3cx2cflOknaStLUyrK3ewwa5lsv0ouQvuAXPe2B/b7qk5OXsJEd/UaADAABg2Gy/YO1WXZuKKmSJ8mShbzLr3FDQXrGR9ZKBkTW5zks2bdhQkSwsGpvotCJ5sqWgaNPG1y4Z/1bU2QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADkPYs6AAAAABBX08714vaC9eVhYEEQjml543JrizoTNq9yno8pSGwsKfJk12sl49apzsKoMwH/jwIdAAAA2Jw6D6rbWvawZHCIzHaTfCdJO0mqllSQsndSUrOkl2X+vMueC6S/1K8ofUzLLJnt6KNVVZ1XJDa0HqyE9nW3Xcy0k7umSBqfYfc2SSsle8HMnw/dniw0v+/NxWVvZDk2QIEOAAAApNqtzouaN7Z+WIGdKNcHJFUO7RFtneT3S7qtsKv0Ts60D7/Kr7RsHRTZieb6pKR9ld55MlAvyXSPJf2m+kvLHxmGiMAWUaDnobULTtxqk3xfU3Jfme1i0lbumiBZ8N+9vEXytZK9ZO5PJK3goZpLfrY8utQYrdZ8dcbuyVD7ufle5pos2XjJSiRtdIVrZFoZhPYP9/DvVYuXvRB1XuD/Vc7zMQm17WaynaWwXLIxHvo4C2yd3DeGCjYEYfhcQVj2ND/EgfjYenbbDmHgsySdpCEX5X3x9VJwe2DBZasWFz83MscYLdxqZ7cepSD4kssPl5QYoeM8J9n18tLrGpZay8gcA6BAzxsvnfvh4nHl444x+amSjtBgegxdT5j57YUdfu24y5etGfaQwNveOv/EHbq6kl9UoOPk2nEAd31JshsTnvzJhEXLXhuxgEAfJs1teXcoO8GlT0hGKEpBAAAgAElEQVSapv59jyYle9Zd/xuGdkvzZSUvjnBMAINQNbf9HebJ883sREmFWTpsaNIvwiD8ZuOiiiezdMw84VY9t+3YwHS+u/bO4oGb3e2qro6SK9dcbeuzeFyMEhToMed1dcHqjudPkvs3XJo8TA+7Ua7rEgq/MWHRsnXD9JiAVp8/c7sw6RdJmqmh/fjpdPPr3BLfrPn2LQ3DFA/oU/X8je8KksF33HTQMDzcXWEimN10ScnLw/BYAIZoUp2XJVtbvyq3uZKKtrR/7Vhpx0ppaqVp0jipothVVmQKTGrd5NrQYWrYIC1vkl5pdr2xtl8xki59f1NnxwVrr9iqf/cYxWpnd7zTg+R3JR26pX0LAmnHKtOUCa4pldKEclN5kWtsial1U/drtr7d9O81ruXN0ivNpvXt3p8YK+Wa3bC07NahPh+gJwr0GGtYcOJUU/Jmk/YboUPUu/uXqxfdfvsIPT5GCa+rC5o7nvuKXF+XVDGMD73BzM+tvPj2nwzjYwI9uNXOa/26uy3U0K9l7KnDTP9Tv7hsyTA+JoABqp3bdojLfyRpSl/7FBVIh71DOmwnaf8pph0mDOwY9eulB5dLf37J9fvnpbbOze7e4OZfaFxcfufAjjJK1HlBbWvr19xtgTbT0V87VvrIbtJBU6X3TTZVFPf/EMlQenqV9PAK6d5nXU9scZo4/0NXl52++vKyN/t/FKBvFOgx1bhgxnSTbpA0dqSPZaarJ64eN9uuu27zXylABqvrThobtnfdJOljI3iYm9s7wjO2u3wZ1/li2OxW50XNLW0/lnTCSB3D3X/SuL7sDF1nfL4C2VTnQfXG9vPN/EL1cc3y1Erp0/tJH9/DNK50eA67sUO691npR39zPbOqz91c0lWV5aXznqmzTcNz5PibOKt1m0SBbjHp4EzbA5OO2EU66X2mA6ZIiSDTXgO3vFla9rjr5kek9e197tbkQXhK46KK3w7PUTGaUaDHUNPC48+Q2/clDdNHz5a59LuWktJPTKn7cd8fTUCK+jmnVCcKNt0nabeRP5rf5yX+ieq6ZRtH/ljIf241c9t+KunkkT6SuW6sX1p6mmT9GlMJYGiq6rzCWttvN/cPZ9r+jmrpy4eaPrJbd9E3EtylP73ouuJ+6am+z7v+LRF2fWzlpWObRyZFfFTPad3fTHcpw6R9ZtIn9pDOOcQ0rWrkMqxvd934D9O1f/W+CvVQsv9pWFL67ZFLgdGAAj1mmhbM+Jyk6xTNa/ebypLwk1a3jN5cbNG6WdMnbCoO/iRpz+wd1f66tmXdh95x9T0d2Ttmbqme275j4OF73Gyau29jgRe7K2EKOszC+lDBK7LkU42l5f9SnYVR581VtfNa6tztwmwdz+TfqF9SnrXjAaPVtrPWTehMFP5KpgNSt5UWSp8/SDr7/abCEZoHPJW7dMeT0rfudb3VmnGXV1zBkY1LSl7JTqLcUzOn/UOy8A5JY1K37Vpr+ubR0j7bZy/P2jZp8e+lWx5zeYZuVZe+21he+iW+YzFYFOgx0jB/5gGB+Z/UjwlMRozpe1UX3/bFyI6PWPC6uqCp49l7ze3wCA5/Y9Ult50awXEjs/W8ln1Ct1MlHStpm37eba2kuy30m+vHlP2WHxL/NWluy7uTsr8pe7M4S1LogQ5uXFT2UBaPCYwqNXM2VMuC+yXbNXXbu7aRvnO8abutIggmqblFmvVz118yl+FvuoJDRmORXj239TiTblHK53Fg0hcOks77oKkga+NJe7v/Rdd5d0hrMnSsmOvG+orS0/luxWBQoMfE+oWfnNjhRc9Iqok6i1wnVC26jRkr0aem+TO+JtPXozq+yz9bfcntP4zq+NlSO6/tMHe/UNIhQ3yo593tosalJTeP+mHW0z1RM7n9ScmzcFlGmqcaykv35gcdMPwq5/mYhNr+JNd7Urd9Zn9p4RHZO2vel9Clax6QLrvPFaZ/Er/iheGBjd+uGDUrl9TMa/ug3O+W1GuKt/Gl0lXTTe+fFlGwHurXS+fe7nok88KvVzYsKftKliMhD1Cgx0TTghnXS/pc1Dneti5I2B4TL7r19aiDIPc0Lpi5t8n/oeGd8XpgTGuSnUW71i69sTGyDCOoduGGKu9KXKnhn7zswcASZ6xaXPzcMD9ubFTPazvJ3G+K6vhu/klmbwaG2ZleWDOu7R5JH+zZHJh0wVHSZ/bPrZ/Dd/1Lmn2HqzPZu91Mj3tYenDDUmuJJln2VM3duFeg4AGlDGvfepx046kje635QHV0SV9a5vpthm9OMy2oX1y2KPupEGcRDQrBQDTNm7mPpM9EnaOHcWEy/F7UIZB7vG56USD/iaIsziXJNSFRsOmiSDOMkKr5bQeFXYl/amRmFj8w9OQj1XPbRtUlAv/lZu4XRJnA3OZEeXwgH1WPa/uWMhTnS4+1nCvOJenje0g3nNS9vFtP7trbrPWaaFJlz4RzfWyg4OdKKc4nT5Du+FxuFeeSVFwgXTPDdNxe6dvcdVHtvLbDsp8KcUaBHgMW+ALl3GtlH21eOPOUqFMgtzR3BOe7tEfUOd522up5J20bdYjhVD239bgg9D+YNJLPq9zkP6md11I3gsfISVVz2w+StEvEMQ6oXdA2OeIMQN6ond3yYZPSOr4uOEo69l1RJOqfQ6aZvjM9fakwl51aO7ft9EhCZUlhSdv3JO3Ys21iufSjU0xbj4so1BYkAmnxMaaj0mY3UMLdb6n8SsvWEcRCTOVY0YdUDXNn7OjSMVHnyMTlVzTOnV4bdQ7khoavnrCnXAuiztFDYTLRdXbUIYZLzZzWmSbdppRr8UaKu11YPbd1VA3LCyw8LeoMkiwM/bioQwD5YPsFa7fywH6klN+7Zx2ce8PaMzliV9P5R6a3u/w7k+a3ZXHe8uypntN2sqQTe7aVFko3niZNmRhRqH5KBNIVnzLtld6FXpMotLwf+YDhQ4Ge4yzwEyRFPG1JH1wTLBFcF3UMRM/rDi0IPPyBolxhIANzneR5MNdG9bz2w2X6ibL8WWDSvOo5redl85jRcZPbR6NOIUlBGMnqB0De2ZQsvkgpk+vuO1ma88H4fC18Zn/TJ9IXKy0Pk355BHFG1IRzfawFvji1/ZtHm95ZG4/XrKRQ+t4M0/jStE3H1MxtOTqCSIghCvQcZ0HwsagzbMHHmubPmBl1CERrdVvNHLn2iTpHBts1fXV6Dg9i3LJJ57VuZx7eoog6P8y0uHZO26FRHDubaua37C4pJ0YEuYX7a7rnZscsEBNbz2vZx+Wf79n2/7N/pw4bz3XfPFppy7+56diquRuPiibRyCgsbrtIrl5DwY/ZU/rU3lElGpytx0mLP5mpQ8GunFznJVkPhNiJ2UfU6LJm/vRxcs/Foqc301WrFk7PsSk7kC1N86bv7KYLo87RFwuDGJ+NdEsm9FNJUQ7sS7j5zVvNX5OjV/4ND3c7MOoM/2Vja6dujPpaeCDW3INvKuV37sIjTDVj+rhDDhtbYvpmhnOvgYKLJY/HqeUtmHRe63YyndmzbVyp9LWPxPPpHbGLdGT69ehT21taPxtBHMQMBXoO61RiN8XjNaoqUOI7UYdA9nldXaAguF5SzvYIm/TOqDMMVvW89pMlHRp1DkmTisKSyNa1zwZzy6n3SeiJnaPOAMTVpLkt73Z5r7PL79lOOv7dUSUaukPfYTpi17Rida/aua0fjiLPcOtKaL5SRootOFyaUBZRoGFw4UdMZSlj31w2b7c6z6nLAZF74lD8jVoWKL3vLVe5H9+8cMaxUcdAdjW1PXe2pIOjzrE5Lu0WdYZBOdMLzT2Xloo7O79nF/ec+rw1t52izgDEVZfbwtS2eYebLJ4nY/9j3oe6l4fryWVfjSbN8KmZs6HaUpYTnlopHf/ueL9gk8ZJp7wvrXn71a3tJ0UQBzFCgZ7DAldl1BkGwl3fZ6j76LFqwczJZvp21Dm2yDQh6giDUTu+/URJ20Wdo4cC7/LZUYcYQZOiDtCLOUvyAIOwzcL1E8308Z5te2/bPTlc3E2ryjhs+sBJszvifUmMJU6S1GtatS8cFL+5AjI540BTSWHvNndnmDs2Kw/e+vnL3bOynNIwqirwIO9mFUU6lywhv1ZSRdRZtshzd/j95oS5+AVuOnnaubH7XOony63ORY903gEgtpLJghOUMlT6rPfH+0xsT2cdnP5ckkHXKRFEGTZm6pW/qkL6ZKynd/2vynLpuL3SXrMDqha0T4siD+KBAj2XWSwn/jipaf7xuT7zPIaoecGMz5p0RNQ5+sdj9zk36bzW7Uw6KOocGYzfUNyaV7MG9zA+6gC9mOVWHiAm3HVyz9sTyqTD3hFVmuG35zbSO6pTWy22Q6ZrZ3e801295mn/xJ5SYR6tY3HcXmlNZkk/McOugCQK9NzmVh91hEExXbt2wYlbbXlHxFHTvJmTJKWtU5qz3FZFHWGgwgL7gHJ2/Xb7UNQJhp+bpMIt7pZNHjKJEDBA2y9Yu5Wk9/Zs+8S7LK+KPUk69l1pXw87xHWYuwfJI1Pbjk0vaGPt3dtJU1LGRJl72vMG/h8Fek7zlVEnGBzbukvJy6JOgRES+DWS4tMBY3oz6ggD5VIOLfnVmwW5m22wdqvLseJckmQ5mAnIbe1dRYcq5bfth/JwPYQP7uxpbWGi6wMRRBkOvXJPGie9szZH+6eH4IOp70PT+yrneQwX/UM2UKDnsIT8yagzDJZLpzfOn5EXS3/gv5rnH3+ypE9EnWMgTHoq6gwD5e45eybEXTvny7q7/695Y+4V6OYqiDoDEDcW9F6Wsqige3m1fPOOKlNVygwwYWiHRZNmCOo8kKzXSjAHTI0qzMg6YEpaU4F5S951eGN4UKDnsAmLlr1m0qtR5xgsM13/Vt0xXEeZJ1bOPqHSzWI3MsLC4M9RZxgok3L5J0pZ5bzWvJphvKNrbc4V6G6512kA5DzXHj1v7rWt0mbQzgdmGWalt97PPQ5qNrbvIPm4nm37Tc6r/t//eN9kS1siL6Fgz2jSINdRoOc4l/4QdYYh2KarvXhR1CEwPAqL/LuScmum6y1r6wwLHoo6xCDkdMdWoQrGbXmv+CgpLci5n/Cea9fEA3Fg6jX6aOfq/Cz2JGmnlOdm0lSd6bH63AgtmXYBws41USQZeRXF0tYp35xuvlM0aZDrKNBzXOj2o6gzDNEZqxfMiMls3+hL08KZH5f78VHnGCiTbqtdemNL1DkGIceXhusqjzrBcOpKBjn3o9a4Bh0YkMp5Pkau2p5tqRNz5ZMdK9OaCieN78jl0VdpAg/SCtTJE6JIkh2pr5mFloczJGA4UKDnuJpFtz4k6fGocwyBhdJ1TfM+zkQYMfVW3THj5X5N1DkGxez7UUcYpM6oA2xOaN4RdYbhVJiDBboUrzNhQNQs6KhRyuoX245Pn0wtX2yXYarW0L02vTWX9c47vlQak+Pd00Ox/Va9Rz24FLPXC9lCgR4DLov7MPEdPFFycdQhMDid7SVXSNom6hwD5vpT5cW3/j3qGIO0IeoAm2OWyOl8A9VVmJNnq3MxE5C7NiXTTgSMLcnfIe4VxRkaPazI0JrDrNdrNjaPi3NJKi9O6TAycfIKGVGgx0D1JbfeJlnsJrrqydzOalo4/ZCoc2BgGufP+LDJT4s6xyAkw0TwlahDDJaZ3og6w2YkJ5aUxHQJyMwSnZaLa45ToAMDUGBBWrGTsYjNE5mem5uNzX6SwXP1XmasvDh/O1QkqSL9+VGgIyMK9JgI3b8sqSvqHEMQyIMbVtZ9rCzqIOif1XUnjTVTLIeIu/n3a759S+yWV/t/Lr0UdYbNeO2ZOtsUdYjh5AWdiagzZMAya8AAhJb+NxME+TvEvSjDJ4THbO4KM+v1LBJ5/HpJUlH6N00udg4jB1Cgx0TNotuelOyiqHMM0bTC9tJvRR0C/RN2dC2WtH3UOQbMtcKS7QujjjEULv0j6gybkcvZ8ocpv08lAcPO0yYEbevM3z+jjZlmAnGP2eVH1us1a82rrt90GzvSOiBi9nohWyjQY6SypP5bkh6JOsfQ2Jcb508/KOoU2LymBTMPlevMqHMMQqgg/HTV4rti/aUXJP2BqDP0xeWxvtwGQH4yT58bI0NBlDc2tKc/N1MQq+8+U+8OhZa8mn40XcumtA6j9VHkQO6jQI8Rq7u/y0KdJqk96ixDEJgFN7w+a3pp1EGQWfdlCH69FMszeJdXXbws9gVk/aVlj0r6d9Q5MghD0y+jDgEAqboSXWtT25o3xvFrrH+aW9KfWxAk0/4NcpnLeuVd0yp1hVGlGXmNG1I6VVyxer2QPRToMVO5+LbnzPzCqHMM0c4lRUFd1CGQ2duXIUyLOscgPN/eEf5P1CGGh7ncfxZ1inR+X/Pi8ryaIA5AfmheXLZKUq8h08ub8/cM+itN6c+tMOh8JYIoQ+C98nYmpTfzuGRd3tz7tkkxe72QLRToMTSx+J1LJeXsENh+Mc1pmD/zgKhjoLfmhTP3lexLUecYhC4Lw9O2u3xZW9RBhktofpVybLRMKL806gwAkJm5UibYfKUpoihZsGJ12hn0xtcuGf9WFFkGK0z686ltmToe8oG79OqalDb5C9GkQa6jQI8hq6sLkwXh6ZI2Rp1lCILA/Acr6k7P81Uv4+Olcz9c7O4/kJSLM1pvnunblYuX5dXkZU1LKurd9cOoc/Twj6Yl5b+NOgQA9MnUq+B74s2ogoy8f77eu5D1lOceC2PLXpLUa1D747m8yOgQPNfgaZPgWRBQoCMjCvSYqv3WshUmzY86xxDtMqa97YKoQ6DbVhVjviZpt6hzDJjricriMO4rHGRUWNj1NUlrtrjjyHO5vvT2GSoAyE2uh3rerF+fPqw4H6xrcz1b37vNQn8wmjSD11RnG830ZM+2h1dElWZkPbQ8fc6A0O2vEURBDFCgx9jES277nuT3Rp1jKFya3zRv5j5R5xjtGubPeJe7zY06xyB0JBWeanXL8nJxljcvHrvapC9EncNMlzcsLft71DkAYHMsSN6X2vbAy/nXr/jQClMybTK1RNpzj4k/9bzx5JvdHRD55q/L05pea1xSwjXoyIgCPcZMckv45yTF6pqjFAUK/AdeN70o6iCjldcdWhCY/UBSYdRZBsrMv1a7aNm/os4xkuqXlC2TPMqh7o9WtJV+NcLjA0C/1C+qeFZSr3PLv3wqojAj6JdPphWw7YXJ4tidQZckhd6rY6EzKf3mmajCjIzVLdKDr6TO4O5/jCYN4oACPeYqL1r2ppnPijrHEO3Z3G4Low4xWjW1VS+Q/D1R5xgolz088eXRMWlZZXnZWZLuj+DQryU7/eMvX215vjotgPxg7tL/9mx5/I38Gua+rk2676XebSbd/cblFstJUksqyv6olBNNdzzZx84x9cunXJ3J3m1m+nk0aRAHFOh5oPLi239iKV9I8WMXNC6YuXfUKUab5oUn7GJm50edYxBazfx0W7YsueVd4++ZOtvU0dnxSUnZHGa+MhEmjmy+onxVFo8JAENirhtT2256JIokI+PWx6RNXb3bQvObokkzdK/WWbtkt/dse/Q16dn6/BjmHrr0s0fTmhvqy8t+F0EcxAQFep7otPAsSQ1R5xiCAnP/oZ95ZuyGWceV19UF7uENkmI3k765zau6+LYXo86RTWuv2Gpt0koPlzTyw+JcLysRHLzy0uL4zQoMYFR7e76MXp9dtzzqWtMaUaBh1N4pXf9gWuHaXFVW9pso8gwXD/ynvW67dE28FxP+j3uflV5OX+7vZ6qzrgy7A5Io0PPG1hcvazLX56POMSSmvVZPWDsn6hijRXP7s7MkHRh1joHz+yYuuvWaqFNEoXmxbWgoLz3KpKWSRur0wl0dXR3vbbikJH1KGwCIAXe/oufttk7p2r/G/4zsTY9IzS2929ztO8/UWawnSm1cVPaQUkaI3fOs9FJjRIGGSTKUrv5zWnOX3K6OIA5ihAI9j1Quuu2Xkm6OOsdQuOzC1fNPiN9SXzFTf8H0KZJ9Peocg7Au4f5pG7niNPfVWVf9krK5QWiHSsO67m2Ty05rWFJ6zNortlo7jI8LAFk1tqPsx5J6rYL+w4cznsmMjeYW6ar7U7/6fH1JQcdVkQQabubf7nkzGUrn/9rlMf62v/EfrudShuq7/KaGpaV5upgchgsFep4pKOk4R9LrUecYguLQwh/49OmJqIPkK5cs0RVcJ6k86iwD5bKvTFi07LWoc+SCVZeWPtCwrnRPM/uMSy8M4aEa5XZBZ3vptMYlpT9lrXMAcffy1dYh1+KebZ1J6Wt3x7fg++Y9rvXtac3fee2S8XFeyec/GhaX/UrSEz3b/vGqdGdMZ+Fv2ihdlr7wXVeBJS6JIA5ihgI9z2xVd+faIAw+q3ifYdy3eVoi7jPT56zV82d8QdKHos4xCL+qvuTWH0cdIqdcZ531i0t/1LikbBd3HWDSpWZ6XNKWJs97SWbXm/vRDeWl2zQsLb1ozdW2PhuRASAbGipKr5Gr13zgDy2XfvBwVIkG7+6nMywXZ1rV2V62KJJAI8LcpXOU8vv1wrtdr8esCyJ0afYd6R0qZrpq5eKSoXSoY5SwqANgZDQtmHGtpDOjzjEEHYGF75548bJnow6ST9bMn7590oKnJY2JOssANXsy3KN6ybL6Le+K3eq8aE3rph3D0LdxhWMCU4F78FYYJldrbNlLTXW2MeqMuaRm/sY9FAa5dZ7GtKphcdmkqGMAcbb17Lb3h4Hfrx6/dwsT0rLPmvbaNrpcA7G8Wfr4ta6NKYtdmnR8/ZKyZdGkGjk1c1p+KLNP92x71zbSzz9nKozJ2Mqr/yxd+se082RvJq101+bFtiGKTIiXgqgDYGQku4rOSxRs+oCkaVFnGaTipCdu8OnTDx4tS2llQ9LsWsWvOJe7n01x3n9vTxj03Nv/A4BRadWlpQ/UzG27TvL/TKLbmZTOvMX1v58zbbdVlOm2bE2r9LmfpRfnkn6Zj8W5JCU8OS9pBUdK+k8H5ZNvSnN/4br8OJPl+KnFe56VLr8vrTh3mX+R4hz9xRD3PFW79MaW0Px0bXmoa84y+f5N0xJnR50jXzQumHm6ZEdFnWPg7JbqRbffvuX9AADorbCrZJakXiNkGjdIp/7UtbqljzvlgJZN0uk3upY3p236d2FX52ciiJQVKy8d22yyE5Xy+/XOp6Rv3ZvbV28+vEL68s9dYWpM05UNi8vviiQUYokCPY/VXHz7g3JdGXWOoTD3ixsXTI/rKICc0Th3eq2ZXxp1joHzVcXWcW7UKQAA8fTG5daWsOB4Sb3OXq5YLR3/Q9fKdREF24y1bdLJP3Y99Wbapk0yzXzj8nFrIoiVNfVLSv8sWV1q+w8elr5+j9IL4Bxw/4uuz97s2pS+uvk/KstK50cQCTFGgZ7n1rau/6pLT0edYwjKTMH1znwJQxME35VrQtQxBsyDM8Ze/IvVUccAAMTXysUlL8iDYyX1Wi/8lSbp2OtdzzfkTsX3+lvScTe4Hn8jbVMo12kNi8v+FkGsrGtYUnKR3H+U2v6jh11f/rmrI70QjszPH5fOuEVqTV2N3vWyF4Yfj/s69cg+CvQ8946r7+mwQKdJ6ow6yxAc+vbM4xiExgUzZ5jp2KhzDMINVYtuvTvqEACA+GtYWvIHN5+hlKHT9eulT1wr/fDh6Iv03z/vOvr7rlcyrdfumt2wtOzWrIeKjHnDv8vOMNcdqVt+9S/p6O+7XmyM9jXr6Oo+oz/nF67O9AtKm5Jh8NHGb1c0RBANMUeBPgpUffu2f0oe63UX3bSkYcGJU6POETfrF35yosljd5mDSa8GJQWzo84BAMgfjYvL73SztJMWHV3SN+6Rzrnd1RTBGhfr26ULfiWdeYu0ri1ts0s6r2Fp2RXZTxaxZZYsqSg9SdKdqZteapSOvV668R8ZrvnOgsff6O7Y+VHmjp3XLUwc2nxZyYvZzoX8QIE+SlSWNH5DpkejzjEE5YG6GOo+QB0qukpSTdQ5Bij0wD8zse5m1uUGAAyrxsWlN3sQfkyutFL8109LH7yq+2x6hjOiwy4ZSsselw670nXTIy5Pr/U2udkpDUvKLh/5NLnp1Tprb3i19FMyuz5128YO6X9+LX3iWtc/X89OnuYWacEvpeP6vDTCn00kdWD9pcUsE4xBo9gZRVYvnP7O0IPHJJVEnWUIzqi65LYbog4RB03zZ35U5r+OOsdAmXRl5SW3fSXqHBg9WAcdGH2qzmvZOwjsdlnm5Whrx0qfP1CauY+ptHB4j92Z7J6V/JoHXCv6nmVlpclO7J4wDZJUPaf1PDNdIinjK3LwjtI5h5j2nTz8x161TrruIemWR13tfV80eldxYtPpr10y/q3hT4DRhAJ9lGleMHO+x3u4+/ogYbtPvOjWLPWVxtOa+dPHJc2elmzbqLMM0AvtHeHe212+LH2QHzBCKNCB0WnCuT62sKTtOkkz+tpnTIl05K7Sse8yvXcHqTAxuGMlQ+mJN6VfPiXd9ZRr7Wa/5fz38vDkhqVjGgd3tPxVM691P7lulbRDX/vsWCV9ck/Tx/eUth/CWvfr211/fMF055PSX5e7kmGfu3a6a0Hj0tLLJYt+MgPEHgX6KON1dUFz+3P3Szo46ixDcE/VJbd9JOoQuaxp/owbZPps1DkGKGlmB1ZefOvfow6C0YUCHRjdaue2Tg+ly0zabKd2eZH03smm9+0gTauSdpwoTRqvtDPs7Z3SqvXSimbXy82mR//t+tur3deab8FquS9sqCj7geqs73JwlNtq/ppxRWHJ1yWdLalgc/tut5W0/xTpXdtIUytNUyZKlRXS/7F35/FxlWX/x7/XPZNkJumeZCZtWYogi0UQ0Z8sIog+Kiio+KQpO7KUzWJLsxbUUaTZWkEqIhXKJnSJu6iPG6BWXB5QFhFka0FoM5NJ12Rmssy5fn8UfUrIJJnJzOezV50AACAASURBVFz3mbner1dfIrQ5H5gsc51zn/t4R9zkuysOvLoDeDkKPNu99/V6eivGGsoBAMTYxB7nqnD7lKcn9S+l1D50QC9C4eZz3maQfBLAFOmWTBHjwqr2DfdKd9go2nz2qQzn13DZ1zcRr6hq3XiddIcqPjqgK6WqQzyF+uNfIOBzAMrT+bOGgClle/86NggMpz9aDxJorcc7dP3rrdP00aITFGjqO5occxOAD6b7Z8u8e38xgD3jnzgZzatE9MXuDt+9etVcZZtuEleEgm0PvExAi3THZDDhluh1tXOlO2zTXX9+BZOzBi4bzgH8Y09Z+Q3SEUoppYpTT4j6Ip3lTR5n+EAi/jKAnRP9sw7vvTq+O5H2cD5IjPsY5h3dnf4rdThPT6R9ypPhzvJT2eBEAA9i77w9IQPDe1+vDIbzzQCW+Cv8h3V3+O/R4VzlgtvexKssYYCizQt+BtDHpFsm4cHqtg1nSEfYJNJct/qNs/9uMgQ4x1e3dT0uHaKKk15BV0qNtPeKeuIsAl+AvVdos3VRi8H4IxN/p3R4eMNrN03fnqWPW/Sqrk0c6vUmz2Om8wHMy9oHZvQR8feZPfeFp5Q9pLcfqFzTAb2IRa+rnctJ8zSASWyhIY3PqW7buE66wga9LbXHO2w2wWUrY5jpukD7+hXSHap46YCulBpLdUNfjWHPqTDOqXDoZBDehvR+1r5CjN+B6CFj8NDWdv+ruWpVAMA0pyF2zDDoVAJ9EODjkd573QEATzHwMIzzkNdf8futIYrlKFapt9ABvchFmhdeROC7pDsyxaBeNjQ/uGJdWLpF0guLTyubUTHtbwCOkG5JDz1etX3a8bRmTeqHliiVYzqgK6XSMS/Evlhf/6HGmEMZPItAM5l5CgBDRLsd8C5yaKeH+Pkkl/8zvJL6pZuLXU3Lnuqk4z3M4+AQEE9hpilgnsFEMTD3keE+SuJfXOL5Z/ilslfQRUnpZlW8xtz5UBW+QNv6uyNNdWcQ4SzplkwQuJIcvh3Ap6RbJM0on/YVuG44R8IwXajDuVJKKTfZEqIEgKfe+KVcoLt1ag+AHgCbpFuUGo+rlsKq3Ega5wqA3fyszU9GWhb+t3SElEjzwmNAWCrdkS5mNFe2r3tGukMppZRSSilb6ICuMLu1q4cIl0t3TAYx39Zdf35AuiPfOHSKl8B3AigZ9zdbhTZV+49YLV2hlFJKKaWUTXRAVwCAqtaNPwTIzZutVXlKBm+Sjsi3aKLmegDHSHekqd9J8kUUCukuqEoppZRSSu1DB3T1H15f4iqAX5PuyBjjnGjzwk9LZ+RLd1PtOwF24/PslwQ7N7wkHaGUUkoppZRtdEBX/zEz9MOdxvFcDIClWzLFcG7dtbR2lnRHrnHoFK+HzJ0ASqVb0sHAL6vaNtwp3aGUUkoppZSNdEBXb1LZse5XYLpDuiNzNHugzPM16Ypc603ULAPwXumOtDB2ehzvJeTiE0BKKaWUUkrlkg7o6i2SyZKlAF6U7sgUgS+MNtV9UrojV3pa6g5l8JekO9JGfFVlx/3uvYVCKaWUUkqpHNMBXb1Fzcr7+h3iiwC4dhMvJnxzZ/M5M6U7so1DIQPGHQD80i1pYfywum2jmzchVEoppZRSKud0QFejCrZu/AMYt0h3TMKcISQ7pCOyrWfguc8BOEm6I009yWSpqx/jp5RSSimlVD7ogK5S2hnb3QzgGemOSbgk3LTgo9IR2bLjunMOJOYbpTvSRYQralbeF5HuUEoppZRSynY6oKuU3r765wMwuADAkHRLhsgQ3d7TeOZU6ZDJYoCGksk1AKZIt6SDGHdVtW74vnSHUkoppZRSbqADuhpT9YoNfyWidumOSTiQjb9NOmKyos11lxDwEemONL3uJc8y6QillFJKKaXcQgd0Na7Ksu4vg/CYdEemCLgy2rzgw9IdmeppXDgHgNvup2eGuXRG2wM7pEOUUkoppZRyCx3Q1bgo9MiwgXMhgIR0S4aImdZEQrWuWh7+H8S3AnDVjvQM3BpoW/c/0h1KKaWUUkq5iVc6QLlDZWvXP6JNdV9mQqt0S0YIB5mE+SqAJdIp6ehprjsXwKekO9L0MnxOi3REMQrW7wmQ8XwAjOMYOBTAgdi7b0EJgCEQdjDQD+aXQfR3cuhvVVN8m54J0aBsuSpGwXquYPQfbED7w5gAM+YCHAAwC8A0ANMYmErAjH3+mAd7P5/3njBm7IHB8N6/5h0A9YG4F0w9TIgaUJTZ6WXD/3K44uVoB+3J77+lUoJCbKp2xoIlpZjrAHOIsb8DU0ngGQBPJ6YZTJgBwnQAIGAq839mg5I3/ncIAIgwzMAeOBgA0U6AdxFoF8PZDqYwGWx1GNuMh16f0u/b9uJqGpD4V1aqEJB0gHIPDoVMNPHsI3DfY77+zWGiUwKt638vHTIRW5edXVVSknwGoIB0Sxpc9d+4IITYG+xLLADxJQBOxt4BJh29BOpKemhVT5vvxRwUWi/Y1PdOOOYp6Y43IWwLd5TPkc7IhhlLdswoKfG90wPnKIY5ipjfwYRDANQI5EQAvAzgJSJ+GaCn2KHHwyv9mwValMqKOdfG9k8acxhR8jBmOhzEhwF0KIC5kLkYlwTwKsAvMtMLBLzAxjxjPENPdLdO7RHoUcpVdEBXaQk3n/M2g+STcNlu4vt4PjHgvGv/m7ri0iHjiTbXbWSgVrojHQxuD7RtbJbuKBbB+thCENqw90r5ZCUAujFc4WtDiIaz8PFcQwf07Kppjs+Dg5MZOBHsnAjQEbD//cZ2gB8H4zEG/W9pcui3r900fbt0lFIjVS6NzfWU8HuJcSyTOZaY3wOgWrorDa8D9CTI+Rs5+GOpd+jRV9tm6H41Su3D9h+YykKRprrFRLhFuiNjzCur2zc2SGeMpadpwRkg+rF0R5r+0efzH3tQ6G637lXgGoHlfUEz6LmHiT+agw//INi/MLyS+nPwsa2kA/okLeKSwPSBDxI5p4HxMQCHSydlQRLA4yD+FTnm15VTfI/qrSBKQtWS/tker/kgCB8E+IMADpZuyjIG6B8A/gDGb4HhX4dXTo1IRyklSQd0lTYGqLel7ufMyMVwkA+OQ/yBYOvGP0iHjGZ7U+30JJlnsHdpmlsMw6HjqzvWu3a3f7eY3dj/Hgf0YzBm5+oYxNjE8H+sWIZ0HdAzEGITjCU+CKAOzGcBqJROyrF+EH7K4HXT4uU/1/trVc6E2AT74u8F4VMAnQHwfOmkPHMYeIKYf0FkftG9xbcJXZSUjlIqn3RAVxnpbTx3P8cMPwWX7S6+j+f6fP5jbLzaG2leeDeBL5TuSAvjS9XtG74inVHoqhviJxnwTwFMzf3R+NfhXeWnYw0N5f5YsnRAn7jKpbG5Hg9dTHv3PMjGrRVutBPMPwA8D4RfKXtYhwc1aSE2wb6BU0FcC+IzcnkC1oWiIP4RJfG9yqnlv9GVLKoY6ICuMhZpXnAxge6U7sgUEa+oat14nXTHvqLLF36IHf4V3PS1yfhr1Y7px9GaNQU/yEmqXBqb6/Xib8jjvYYM3BrpLP9cvo4nRQf0cdSyp+bA2MeYaBGAjyP9jQgL2WYAqwdNYu2O9lm7pGOUu8xZNnB4koYvYKLzCdhPuscFdoL5Bw6Zu3o6fZsAYukgpXLBPUOAslKkqe57RDhLuiNDVi3L7g2dO81JDD8N4ADpljQMeAzeM2vFhr9LhxS0EJuavvhvmfD+fB+aCLXdHeXfzfdx80kH9NHNWLJjRlmp70owXwlgf8kWF9gD4G7HY24p1qchqImZH+LSnliijpivAnCcdI9rMV4E6G6v4Xte7yh/TTpHqWwy0gHK3ZLGuQJgt27m4YXhOzlUWyodAgBOItkOdw3nAGG5Due5VxNLnC8xnAMAM26bs2x3lcSxlYyqxv45gfpYR1lJ6StgXgEdzidiKoDFJun8M9gQu6+mOT5POkjZJbC8Lxioj38p2h9/hZjvhQ7nk0M4BMRfHWZsDjbE1gfrY++TTlIqW3RAV5Myu7Wrh2CukO6YhKOiCc9y6YieltqTAb5cuiNNf6h60fm6dEShmxdiHzNL3t9flTTeZYLHV3kSbE68LdgY+7qH6UUiNAA0TbrJhQyA8zjJzwcb4rcHlvcFpYOUrJrm+LxgQ/zbNGReIeIQgBrppgLjBVAHwp+C9bE/BBpin0GIdb5RrqafwGrSqtrW/wCE9dIdmePrepbXvVvq6FtDZ5SDzR1w1y0n/QznIurq0s2RciwWS9RCfmXF1TObtk8XblA5Mufa2P6Bhv67kHReAOMaAH7ppgJQAvAiGqLngw3x5fNDbMVKLZU/s5fFDww2xG/nJD8P8KUAyqSbCh7hBAK+G+xPPBlojJ0FsJveVyn1Hzqgq6zwlg1cCbBb7wHywsFaXrSoROLgJQn/VwEcInHsjDGWBdq69D7LPCB2LpBuADC11PGdLh2hsmvGkh0zgvWxtqQH/yTQRdD3BDlA0wC+Mdofe2L2svgHpGtU7s1t2V0ZaIh9wzH8PMCLAIi8tyhufCQxvlfTGH88WN9/hnSNUunSH8YqK2aGfrjTgC4B4NYdNY/umbWrMd8HjbYsfB9A1+T7uJP066r2DWukI4pBsH5PAKBTpTsAYO8zeVUhOGQxlwUbYkvLSspeBKEJesU8D+gIx/AjwYb+O/dbumuWdI3KgUVcEmyIfX542PsCAVcD0FUTwphxDIh+HGyI/SZYv+dI6R6lJkoHdJU1lW0bfgnGWumOTBHwxe3L6/L2DfyFxaeVMfOdcNcji3YZD11M7j0R4zLmfbDl+zTjeOkENXnVTfH37/HFnwDwNQCV0j1FhgC6eMhb8mywsf9M6RiVPYHGxH8Fp8eeBHAzgJnSPeotTgV5/hZsiN1yQPNOfX2U9ex446cKRjJZ+nkQXpLuyFBpMol7OHSKNx8Hm1kx7QsA5ufjWNlCzJ+rvHH9v6Q7igZZtcvv/vrGxr2C9VwRrI+1GYd/C+Bw6Z4iFwDTj2rqY/dWh3iKdIzK3IwlO2YEGvrvInZ+CdAR0j1qTF4AiweSpc8H6+PnSMcoNRYd0FVW1ay8r58d5yIAjnRLRgjvjiaCS3N9mHBT3dEM5H1J/ST9qKp943ekI4qLXW/4BpzSw6QbVPqC9f1nMMWfe2M5u/7ctwQTzjd98b8FG2M2nYhTE1TT0H96aUnZ02/s36DcowrE9wcb4j+d2xjbTzpGqdHoD2qVdYH2rk0ErJbumIQbeltq35GrD86hU7yG6E64a+OYqGOM2x4DVwjmSAe8GQekC9TEVYd4SqCh/y4Q/ZgAfSNqI8IhYPw+2BDL+YlhlR1VjTy1pj52L4N+ql9XbsanDzOeCjTGz5cuUWokHdBVTuzx+ZsBPCPdkaGyJJs7ubY2J/eG9ySCTQAfm4uPnStMdGVwxbqwdEcRsut5uWyqpBPUxMxe1n+sJxZ/XK/uuYIXwNeCjbF1wXqukI5RqdU07Znv4cQfmaBDXWGYScz3Bhti9+ntJsomOqCrnDgodHcCcC4EMCTdkgkCjoseYhZn++NGW84+nIDrs/1xc+y+QOv670pHFB8mAEHpin0x8wzpBjUepkBjbJlj6FFmHCpdo9LAWAhK/Km6IfF26RT1VjWN/Vex43kMYFftHaMm5Dzqjz8WqO87SjpEKUAHdJVD1W1djxNxp3RHxhg3RhrOydobJQ6FDLNzBwBftj5mHmwtHXCWSEcUo/2W7p4Jyz5XjHHVbRlFZ8aSHTOCjYmfEGMl9BFPLsVHGjh/rmmInyxdovaaF2JfsCF2HzPdCsu+J6vsIeAwIvPnYEP8YukWpXRAVzlV2TsjBNDj0h0ZKjee5N0cCmXl6yQ68OwSACdm42PlCTPj0uk3dW2XDilGw6VmtnTDSMykA7qlqq5NHFpWUvoomD8u3aImbSaDfxlojJ8rHVLs5izbXRWLxX8B4DzpFpUXPoDvDDbEb0eI8/JEH6VGowO6yilas2bIMF0IICHdkgkGTuiNP3flZD9O9/W1B4Hx5Ww05Q/dHmjf8HPpimKVdLyzpBtGIjg6oFsoWN//SY/Hecy2Xf/VpJQS8301jbEm6ZBiFajvOyppvI8R4wPSLSrfeFGwP/GjWYt5mnSJKk46oKucq2xf9wwz3SDdkSkmbg831B2c8Z8HyDNs1gBwzwYkjM1wYm57DFxBISLrllLy3s2slEWCDfFmEP0AwFTpFpV1xIy2YEPsa2/sSaHypKY+fgqR2QTgQOkWJYVPL/ElHp1zbWx/6RJVfHRAV3lR7T+8DaBN0h0ZqjAeXsNARm+QepvqrgDw4Sw35ZID43y2uuPHe6RDiplxktbdQ8wgHdCtwVTTEOsEuBUZfm9SrrE02JC4TYf0/Khp6D+diX8GPemlwPOTHmya05g4TLpEFRcd0FVeUCjkOEm+CECfdEtm6NRoy4JL0/1T0etq5zKwIhdFOXRTdWvXb6Ujip0Dsm5AJ+gmcTY4ZDGXBRviGxiol25R+cKX1zQkbtUhPbeCDbE6Bv0QgF+6RVnjgCQ7v6u+tv8Y6RBVPHRAV3kT7NzwEhNdJ92RMaaV25tqD0jrjyTNt0Fw06OpnksMOF+QjlAAkYW7cLMO6NL2W8r+Pb7YgwBqpVtUfjH4Sr2SnjuBhvgFAO6HnohUbxUwHvNwoCl2gnSIKg46oKu8qm5dv5qBX0p3ZGhaksydE13qHm1ZcCGA03LclE3D5DgX7n9TV1w6RAFMFl5BJ13iLumQxVw2WJL4HkBuumUmYywdYCW+PNgQ+6p0RaEJNMQ+Q+C1ADzSLcpWPJ0c+tnsZf3HSpeowqcDusorAtjjeC8BY6d0S4Y+3NO88MLxflOkobaGQV/LR1DWEFZUdXT9RTpD7UWOfVfQmXQXdzGLuGSPL76BmN100m9S9DJxKrQ8WB+7RrqiUASa+j5KwAPQ4VyNi6c7hn4RrN9zpHSJKmw6oKu8q+y4/zU25Np7Jwl8c2/jufuN+ZuMuRUM6x6TlRLjiaoy50bpDPV/mBzrBnTSJe5CmILT42sBfFK6RFmCcFOwPrZQOsPtqhviJ5Fjvg/Yd0JUWasS5PlV1bWJQ6VDVOHS5YpKRKB1/Z2R5gUfJ9CnpVsyMN0xQ98C8InR/mGkacECIpyV56bJGEjCuYBCXYPSIer/kIU7pusu7jKCDbGvAHSedEdOMfpAiGDvRqIxgPfZUJSmg1EKQhWAKgBlMpFWMSDcE2iKvRppL39UOsaNqq5NHGrg/BBAuXSLBRIAegHaDuJBMHYDnPy/f0wlIEwhYCozKgFUSoVaosbjcf4nWL/nuPDKqRHpGFV49M2WEuMMl13h8Q6cCFBAuiV99PGe5rpzq9s23L/v393d8unKAaZbpKoyQcRfrGnrelq6Q43AIF3jq4IN8YsBvl66I4teBvA4QE8A/BIRNsOT3NzdOrVnoh9gZtP26V6n9CCCOdgABzPwToCPBegwFNfKwFJifLdyaey9vTeVvy4d4yb7Ld01a8jjPAi4aKXb5O0E8CSApxj8rHGwBfC+YqaWbtkaolhaHynEpnJXfLYppYMoiXlEzmEAHQ3gKBTPs+MPAjw/mBfiD20JUUI6RhUWffunRPU01S0EYZ10RyYY1MuG5gdXrAv/++/1tNTdD8Y5kl3pYNAfq19KnkRdXcnxf7fKp2B97BoQvi7dMcID4c7yc6Ujsi3Y1PdOOOYp6Y43IWxjmAuJnZ/CrbtKM/qIaBOIH2GH/ndgOPHXnTfPzNn+I1WNPNVg4DhynA+B8CEA70ZxDOx/9lf4T9EhYWLmh7g02h//BYBTpFty7BUGP2zI/C7JtKmn0/dCPg4aWN4XNMPmJAZOAvN/AXREPo4r6IFwp/88gHRfS5U1egVdiapu37C+p7nuUwDqpFvSReBKcpw1eOO+0J6mhR8Hs2uGcwAxIr5Ih3OlLMSYRuAuuGs4HwLwe4AeZvDDkd3+v2ANDeXr4NEO2gPgV2/8QtWS/tneEpzFoP8G8AEU7rD+vnhf7JsALpYOcYNoLPENFOhwToS/sUPfYyR/Elk5ReSkY2TFlDCA777xC9XNiUNM0jkDe9/nvU+iKcfOCTQk/hnpxFekQ1Th0CvoStzeZeGlfwdQI92SCQYWeHzeXziJoWcAGnvzOIsQ0+eq2tffKt2hRqdX0PPHyivo7jFIjAcZ9L2B4cTPcnmFfDJqmuPz2HEuBehiMGZL9+QCM50fWen/jnSHzQKN8fOJ+V7pjiwLE3Afc/Ke8Mqpf5eOGcucxsRhSU5eANClAFx4e2NKDsOcFun0ufUxwsoyOqArK/S01H0CjJ9Id2SGIwA9DDetAmD8pqp9w3+RPmrYWjqg548O6JngZ8H0LQ8PP7B11bSodM2ELeKSwPTE2QSnufCW3vJusHlXeKV/s3SJjeYsGzg8Scn/BWGKdEt20NMAbp6a8N3/4moakK5JxyGLuazPnziHGUsBfqd0T5ZEhofxbt0PQmVDoS73Ui5T3brhQQKtle7IDAXgpuEc2OWBc7EO50qpDDxE4I+HO8vnh1eW3+Kq4RwA1tBQpNN/b7ii/EgG/hvAc9JJ2UPTAP4OQqy3L46w31L2J42zsUCG86dA/Mlwp+/ocKd/rduGcwB4cTUNdHf47wp3+o4mYAFAz0g3ZUHA48U6/fpT2aADurIG+TxLAbwi3VHoGLRkVnvXq9IdSin3IMYm49DJ4c7yD3V3VvzM9RsihciJdJZ/L1zhfyeDrwJQGI9KIpwQ6EtcJ51hm2FvYpXbr9Qy8BqAc8IV/mPCHRU/dv3XIACAuLuzvCtc4TsKoEsAhMf9IxYj4KRgLBaS7lDupwO6skZl6P7dBHMx9MpuLv0k0Lb+bukIpZRrvADwGd0ry0/atsr/O+mYrAvRcKSz4raBoYHDALodBfDzh4iXB+v3HCndYYtgffxUBl8h3TEJg2C0E/sPD3eWr0OIHOmgrAuRE+70rx00icMAfB2AezevZWqqaYz9P+kM5W46oCurVLWte4gI35DuKFBRTjqLpCOUUq4QA6hlasL/znBnxYPSMbm28+aZO8Od/iscQx8gwvPSPZNUCvKsQYiL/j1edYingPgOuHbPJXqa2XlveGV5c3gl9UvX5NqO9lm7wp3lS9jAzV+HXma+e16IfdIhyr2K/pu3ss9gWawZcO03Zmsx89WBzq5u6Q6llPX+kEyaY8Kd/jY33t86GT3t/k3eIf+7QLhFumWSjq+Jxa+SjpBG/fE2AAdJd2SACVg5NeF7r9Tj0iRF2ssf9Q753wXQmpH/zB1LXOiIWH/8y9IVyr10QFfWmRP6Scw4uBBuXuJkHVoXaN+4UbpCKWW1BIBrwp3+k6Jf8xXtSdLXbqJ4uKP8829sIrdHuidTzFgxtzHmmkd/Zlt1U/z9BLjwJAXvBvOnuzvLG4rtBNm+XruJ4uFO/+XMdD6A/6wecMtSCAKW6VJ3lSkd0JWVKjs2/IlBHdIdhYG3lQ4kPyddoZSy2nMOnOPDneWrC2PzqcmLdJZ/L5k07wH4WemWDE0dZrRJR4ioZY9xeDXcM88BAIjwvMfxvi+8suJH0i22iKz0f4fZOQGA2za39TDwTb3VRGVCP2mUtap9yRCAolvalXVsLpt+U9d26QyllLXuB/vf09M55QnpENtEv+Z7ftAMHA/gN9ItGTon2Bg7Tjoi3wIHxi4F8C7pjjT9ySSHT9y6qqyAHv2XHZGVU55KDvFxAB6TbkkL49hAX+wy6QzlPjqgK2tRqGvQYVwAYFC6xbWYvl3dvv6n0hlKKSslCWgKd5afVwwbUGVqR/usXVUV/tMBrJNuyQCBcfPeW5qLwwHNO2cS0VelO9JDP/NU+D+0ddW0qHSJraI3V2wD+0+By06WEdGNc1t2V0p3KHfRAV1ZLdi+4UkGviLd4UYEbDF+T710h1LKQow+Ap/Z3VmutxJNwDMhGgxX+M9j4Fbplgy8L1CfOFc6Il8GkqVfAlAl3TFRTPTzqQnfWVtDFJNusV14JfX7K/yfAJGbLjxUJodLXHbCSEnTAV1Zr9oXbgfwZ+kOl3HY8MWVoft3S4copayznYGPdHdW/Ew6xFVC5EQ6/YvB7nsUKBHfMD/EpdIduTZ7WfxAAFdKd0wc/7K83HdWMW8Gl64tIUpUlfvOAsg1378YfNmcZQOHS3co99ABXVmPQo8Mw3EuBBCXbnENxi3VKzY+LJ2hlLLOFgfmuMjK8j9Kh7gTcXil/xqAbpcuSdO8aCx2kXRErjnG+SIAt5yIeAxcftaWECWkQ9zmmRANeip8tQz8XrplgjzDlLxBOkK5hw7oyhWqO7r+CcJy6Q6X+Gdi0NH/Vkqpkf4FplN7On0vSIe4G3F4i+9qYnxfuiQtTNcfspjLpDNypboh8XaALpDumKAtDpwzdO+HzG0NUWzIJM4A6GnplokgwmdmN/a/R7pDuYMO6Mo1qsqOuAUMvSo8tmEiunD/m7p0tYFSal9bHZgPhVf6N0uHFIQuSnqT/vOIsUk6JQ377/HFF0lH5IqBEwLgle4YF6OPTPITPZ1TuqVT3G5H+6xdxsEZACLSLRNADuNG6QjlDjqgK9egUMgZJroYgN5XnQIB7VWt6/V+faXUPmgXmeRH9Mp5dr12E8UND38awBbpljQ0YBGXSEdkW9W1iUMBLJTumBDCou72qc9IZxSKbav8r7DBpwG44D5++sjsZfEPSFco++mArlxldtv6LQCWSXdY6slKn6M73iul9jXERLU6EOTG1lXTog6cTwNwyw7c+wemJeqkI7LN6+ElcMN7WsY3wp3lbnxcn9Ui7eWPEvG10h0T4Rg0STco+9n/zUypEarbNtwBsJsesZEPg44xF1CoS58Zr5TaB18V6fD9SrqikPV0TnmCiVyzdJzA9YX0XPQ5y3ZXMfhC6Y7x0dNTB/z66NMc6e6o+CYzvivdMT4+LVDfd5R0hbKbDujKnUzpfmq/QwAAIABJREFUZQzqlc6wBTN9Obhi3VPSHUopexDoW+HOijukO4pBpMN/PzPfI90xIYSjA039H5HOyJakKbkCQLl0xzgG2CTP18ep5daQJ3Ep7L/lhIhMo3SEspsO6MqVqld8ZxvBWSzdYQd6vHrHtE7pCqWUPRj4q6/Ct1S6o5g4pnwxGC9Kd0wEOZ5rpBuyYe+u9Hy1dMd4iPClSPuUJ6U7Ct2O9lm7QHQpAJZuGUddTXN8nnSEspcO6Mq1qts2rgPRRukOYQlDyQtozZoh6RCllDV2ksfU6vOV8yvaQXvYgwsBONIt4+OPzmmKHyBdMVl7fPGzANRId4yJ8WR3uX+VdEaxCHf4f0Og26U7xuFFkj8nHaHspQO6crWhQboaQNE+qoSJmipbu/4h3aGUkjPyUhETXRNu870sElPkIu3lj4LwDemOCfA47FwqHZEFl0gHjMOBwRUI0bB0SDEZJl8jgK3SHSPxm//6ov2Wsl8sRllNB3TlanNWrYuC2TWb82QXbaouO9wNbwSVUjm0725fxPh+pMN/n1iMglPuvw723wcLZroYIbb/ueEpBJsTbwNwqnTH2OiOcEf5n6Qrik20g/YwkXX3eY/YmbFyuCSxQKZE2U4HdOV61e0bf0LA3dIdedbvJPkiCoVcsJRSKZUnYZQkr5COKHY9IepjYjfc/z832B/7mHRExpzkxXjLzGOVPVyS/KJ0RLGKdPgeIMYm6Y6xMLN+v1aj0gFdFQTyeT8P4FXpjnxhos8HOze8JN2hlLII07XdrVN7pDMUEOmo+CGA30h3jI/OkS7ISC17wHSRdMaYmNojK6aEpTOKFzEZXgq7N4w7rvra/mOkI5R9dEBXBaEydP9ugvks7P5GnBUM/LK6df1a6Q6llFV+E17pf0A6Qu2Dk0sAJKUzxnFmsJ4rpCPSFTwwcTKAudIdY9hakvR9TTqi2G3rqHiMGD+Q7hiL8dBnpRuUfXRAVwWjqm3dQwzcKt2RU4ydHsd7CRXBiQil1IQNGvLoYyctE1459e8Mtn0/gApQ/EzpiHQRoVa6YRwdr91EcekIBYA9X4DdJ8oWoJY90hHKLjqgq4Iy7Is1AXheuiOHrqzsuP816QillEUYN23rKHtWOkO9FbH5CoBB6Y5xLJQOSEstexh8lnTGGLpLhv1rpCPUXt2ryv4BQpd0xxiCgYMGLN/sUOWbDuiqoMwJ/SRmyLkIdp8tzQzjh9XtG9ZLZyilrBId9CRapSPU6MIr/ZsJZPstSR9x0zL3N5a3B6Q7UmFglV49t4uHuVO6YSzkJM+WblB20QFdFZzK1q4/MnildEeW9SSTpZdLRyilLMO4YUf7rF3SGSo1ZnQAsPk52D4g9mHpiImyfHn7niGT+LZ0hHqzrZ0Vf4XNmzYSfXpeiH3SGcoeOqCrgrSrf8+XADwl3ZEtRLiiZuV9EekOpZRFGC9WTfF/SzpDjS280r8ZhO9Kd4zJmI9LJ0wME4PPkK4Yw1o9YWYnAtu8ad+MeL97TpKp3NMBXRWkt6/++QARf0m6I0v+UNW64fvSEUopuzDRDc+EyPb7mxUAk7R8VRfzxwG2+ZniAIBAU/9RsHf3dodhVktHqNF1V5T/D4BXpDtSIZjTpRuUPXRAVwWJQ6d4malZuiNLTuhtrvuIdIRSyiovRSp8+lg1l9i2quJxMB6V7hjDnOqG/qOlI8ZDjuc06YbU+KFIp+8l6QqVQogcgO6QzkiFwRZ/bqt80wFdFaRoPLgcwPukO7KEHGBNb+jcadIhSilb0AqEyOb7mtUIbMjq2xEMm1OkG8bDZPEQw3SndIIaW5KctbB3E+F5NcsG3iEdoeygA7oqOD3L694NwvXSHVl2oBNP2r1EUimVL6+Ed/lsf762GqG83NcFoFe6IyXCKdIJY5nZtH06MU6Q7kihd+qA/wfSEWps0Y6KrQBbu1mc40naewJK5ZUO6KqgvLD4tDJ2cA+AEumWrCO+LNKyQO9RUqrIEeFWrKEh6Q6Vni0hSgCw+baEkxBia98XlnDZBwF4pTtGR999cTUNSFeo8RHMOumGVIihA7oCoAO6KjAzK6a1E3CkdEeuEOOOXUtrZ0l3KKXExD2eYdufq61SIasH9FmBeP87pSNSMaCTpBtSIcIG6QY1MYMJ3/cBJKQ7Ujgei7jwLjCptOmArgpGtPnsUxlYLN2RWzR7sMzzdekKpZQUuv/11mn2LpNWYwp3+P8MxovSHSk5ZOsScjDj/dINoyJs697s+510hpqY7atpN4BfSXekUB6cFn+3dISSpwO6Kgjbm2qnM5y7UBSf03xepGXhf0tXKKXyj03yG9INajKIQbxeuiIVgrFyOAjWcwUAK9vYwQ/QRbZuPKZGw/wT6YRUGDhRukHJK4JhRhWDJJnVAA6Q7sgXYr4tvPzsoHSHUiqf6OlI+5QnpSvU5BgHP5RuSIWIj5VuGN3A8bD0/nND/FPpBpWe5DAeBMDSHaMxOqAr6ICuCkC0ZcGnAJwv3ZFnVcZxbpeOUErlEet9roVg26qKxwFske4YDTPmH7KYy6Q7RmKwrUNLzDtc/rB0hEpP9OaKbQAek+4YDZMO6EoHdOVy21pqq5lRrIPqJ3uaFp4jHaGUyg+HaKN0g8oSxoPSCSmU9vtj1m0URwbvlW4YFdHDr91EcekMlRFbH7cWDDYn3iYdoWTpgK5czctmLUAB6Q45fGtv47n7SVcopXKLgb/2dPpekO5Q2cK/lC5IxbHxXm/mY6QTRsPMj0g3qMwwjLUrH9hx3iXdoGTpgK5cq6dlwWUAPiHdIYowI+kZWssASacopXKI6cfSCSp7BoYHfw/Azo3F2K6N4qob+moAzJHuGA0RNkk3qMwQl/0BwKB0x2gM+CjpBiVLB3TlSt3X1x4EplXSHTYgpv/qaVl4sXSHUiqHPGzrY4FUBnbePHMngKelO0Zn10ZxHpBVJwz2Easq9/9VOkJlJryS+sGW3ofOdLR0g5KlA7pyHQ6FjGfYcxeAqdIttiDmm8MNdQdLdyilcmJPZIf/f6UjVNb9VjoghaPmh7hUOuLfHDZWnTDYx5+fCZGVV2DVxJDBn6QbUtABvcjpgK5cpzfxXAPAJ0t3WGaK8fAaXequVEF6CGtoSDpCZReTtfcvl0b7+g6Vjvg/ti735T9IF6hJcvBn6YQU5s1s2j5dOkLJ0QFduUpv09nzGRyS7rATndrbXHe1dIVSKruI8GvpBpV9JZ7k7wE40h2jYeOxZkAnosOlG0bj6IDuesRk64BOJfDNl45QcnRAV67xwuLTyhxyHgDgk26xFQPtPS111ryxUkpNHoFtXYapJuH11mm9AP4u3TEaYrLj50gtewA+RDpjFMlhM/hH6Qg1OdtW+V8BsF26Y1QO2fh5r/JEB3TlGjPKp30FgKVL3axRzkx3c22tRzpEKZUVA7PKy5+SjlC5Qn+RLhid83bpAgAIHjxwIOw8Kf/CjvZZu6QjVFY8Kx0wGkOOPgu9iOmArlwh3LLgRBCWSXe4AYGPjx5srpXuUEplxZO6EVUBY35GOmE0DLJiQKeh5GHSDSlYOdSpTPA/pQtGw0y68W8R0wFdWa+7/vwKw3Q3AL0qPHE3bF9ed6R0hFJqchjQ3dsLGBtj5YBOgBVL3JnI1gHdyqFOpY9Btp5s0QG9iOmArqzn8Q7eDEDvxUlPWdLBvbxoUYl0iFIqcwTS5ywXMGcwaeU96ACCNuwizWTnz34iek66QWUHgW19LXWJexHTAV1ZLdy04KMALpHucKljojN3tUhHKKUmwdIl0Co7ojdXbAPQK90xGh+XiS9zJ+AA6YbRsGPtUKfS5Hg8tr6WweoQT5GOUDJ0QFfW2rrs7CpDdDf02d6ZI3yhp3Hhe6QzlFKZKfMOPi/doHKLCVaehHHYivvQD5QOGM3A8IAucS8QPS+VbQaQkO4YVf/AbOkEJUMHdGWt0hLnmwBqpDtczgvD92wOXWTjLrhKqbFFXm2bsUM6QuWWYbJyQAfIhuF4f+mAUXTvvHnmTukIlSVdlAToBemM0bG+By5SOqArK0Wb6i5goFa6o0C8oyKR+KJ0hFIqPawbURUH4n9IJ4yKOCh5+KpGngpgpmRDCrYuiVYZ45elC0bj0QG9aOmArqwTva52LhNulu4oJARuijTVvl+6Qyk1cQTSAb0IOA5el25IQXQ48Dh9NlzBfwtmfkW6QWUbhaULRsMMXeJepHRAV1ZhgOCYO2HnWXM3M0Tmjn8trfVLhyilJoixRTpB5R4BW6UbRsUQvYLOHporefzUKCJdoLKLyLFyQJdexaLk6ICurBJtqfs8Mz4q3VGgDvOVmhXSEUqpiSFj6eCmssrjoW3SDaMTHg7YExA9fmrd0gEq26w96aJL3IuUDujKGtGWsw8HQwfIXCJc09O88BTpDKXU+BxK6oBeBGb6fd0AWLrjrUh0OCCHKyWPn5q1w5zKFMPOK+igKukCJUMHdGUFXrSohOHcB8BNS7AdAC9KR6TJgHltJFSrz9ZUynLWLn1WWfVMiAZh57PQZ84PcanY0YmrxY49BgLpFfQCQ46d96ADmCodoGTogK6sEJ218wtguOp53QSsJgdnAhiQbkkL4SAaMCulM5RSY/MaRwf04mHja007Y3HBZebGzquHnmFbhzmVIfJYOqATpkknKBk6oCtxPc21xwLULN2RFsZmx+dcX9Wx4VmA2qRz0sZYFGmqO006QymV0uDrrVO3S0eo/CC28z50ZhYc0O28go4k2znMqYx5TcLO2xZYB/RipQO6ErU1dEY5YO4HUCLdkgYHxvlsINTVBwBVvuQKBv4uHZUmIsIdO5vP0d3ylbLTToAsvC9Z5QITR6UbRjNkTLng4WcJHjuVZPiVKTbejqAm4dW26TsBDEp3jGK6dICSoQO6EuUd8HcAOEy6Ix0E/kZ1a9dv//P/Q12DxnEuAZAUzMrEnEE4N0lHKKVGtUs6QOUTxaULRmOS5JM6Ntm5vHc3ushtP+vVuIgB9EtXjELvQS9SOqArMdHmBR8mpqukO9LC2Oz4+LqRf7uqo+svAN8ikTQZBL4w3LzgM9IdSqm30AG9mDAnpBNGRUmxAZ0Z9m1mSrDzdVLZYON+Qn4sYjetMFVZogO6ErEj9KkZDLoTAEm3pOFNS9tHGvLFrwfhpXxHTZYB3dZdf76tz5tVqljpgF5EyNLBj0juCjpsvHrIVg5xKjtsXOKO6jkok25Q+acDuhIxnPB9E8AB0h3pGLm0faQ5oZ/EQHwZrHye7ZiqPZ7B26UjlFL/h1gH9GLCsPMKuuMIDugWXkFnO6+yqiyw9SSZP7FLr6AXIR3QVd5Fmxd+GuCzpTvSkmJp+0jVKzY+DMbafCRlFeFTPU11C6UzlFJ7OeA90g0qj9hYORwQOUIDOhMIkhvUjYp0QC9YzGTlaztIHq90g8o/HdBVXvU0LpzjAN+W7kjTmEvbR/LAWQbg9Rw35cJt0etq50pHKKUAImPlm0WVG0xs5esttcS9OoQK2Pke1crXSWWDnV+Dw0mjV9CLkI3f/FSBYoBg+NsErpRuScd4S9tHmtXetQuEK3LZlBOEGZw035LOUEoBzDws3aDyx4Ct3MXdYYgM6CV79kje+54S6T3oBYvYziXuJTqgFyUd0FXe9DbVXQHgdOmOtExwaftI1a0bHiSgKxdJOfaJSPPCi6QjlCp2ZKADehFhwpB0w2hI6PGhQ8ZYuayXyc69AtTkMdl58iVpyMqvBZVbOqCrvAg3n/M2JrRLd6QpraXtIw0OmasA9GS5KecIfPP2plpXbeCnVKEhtnNgU7lBDCuvkpHQ0ntn2Hgkjjs+Y+VO3yob7LwH3euQld8bVG7pgK5yjkMhY5C8GzY+MmUMRLg1naXtI81ZtS5KxA3ZbMqT6UmYteyuR+ApVVAYOqAXE2Y734Sz0OZ1pZZeNSR931ywiGHlSaFBZke6QeWffqNROdeTeLYFwEnSHWlhbHbKnOWT/TBVrRvvAfh/spGUV4QPvXFLglJKArHI0mIlgwlWDqQQui/X1mW9DNZnUhcoJjtfW49hPVlbhHRAVzkVWV77LgK+KN2RpkktbR/Jw3w5ANc9MokJnZGGc94u3aFUUWJdwVJMiCy9gm5k7rn22nvCwsohTmWFla+tVwf0oqQDusqZFxafVmYccy+AUumWdEx2aftIs9q7XmVG2hvNWaDCeJJ3c22tlcu+lCpkti55VrnBlt6Dbhyhe9CTZOXPHSaZXe1V7rGlA/ogO7phaBHSAV3lzIyKaTcy8E7pjrRkaWn7SNX+I24FaFO2P26uMXBC9BDzeekOpYqNMXbeD6lyhSukC0bDRuYedANYed8tgVx1wUFNHIGtPPlS6nX0CnoR0gFd5USkqfb9AJZId6Qpq0vb90WhkAMneSlg53M2x8RY0dt09nzpDKWKia1XVFVuGJCVm6gyyyxxH7Z1WS/bOcSpbCArr6DH+6ba+bWgckoHdJV1kVDtFDLmbsBdV4CyvbR9pOqOrn8y8425+vg5VObAuZcXLdKBQak8YUt3FFa5weBp0g2jcZJG5FGhHoftXNZLdi6DVllh5eoIXyXs/FpQOaUDuso6Eze3gHGwdEdacrS0faRqf6QNjL/m+jhZR3h3z6xdjdIZShULAvulG1ReWXkFvbw0ITKgD9o6oFt6n7LKChtXRzhbQ4hLR6j80wFdZVVPy8IzmfBZ6Y405Wxp+0gUemSYPc4lcOEzjgn4Uk9z7bHSHUoVA7Z0ybPKGRtf78FX26bvlDiw15O09GekLnEvYDa+trsBYukIlX86oKus2dZSWw3mNdId6WLgm7lc2j5SYEXXE2DclK/jZVEJYO7kUK2Vy8CUcrt934UR2bnkWeUIY5Z0wiiiUsOBM2VKTOK446Nphyy283nZKnPzQuyDnSfJdksHKBk6oKusKWFzG4CgdEdaGJvhc1ryfdidsd1fBPBsvo+bBUf3Dni+IB2hVCF684PP9Qp6USHMlk4YiYFuqWP3hNAPICl1/LHE/fFq6QaVXQN7Epa+dyUd0IuUDugqKyItdZ9l4DPSHWliIl6Uj6XtI7199c8HQM6VePNFM1dg5uZoY+3/k+5QqrCRXkEvFiH2AqiSzhjJgCJyRycGKO8/myfCSbKlw5zKFMMJSDeMjndJFygZOqCrSdvWvHAeMW6W7kgXA7dWtW38tdTx9y6rp9uljj8JXjbmnn8trdVNrJTKFWIblzyrHKjaGauGhe/HGBwVLrDy6iEbl60UVOOy9TVl0ivoxcq6HwjKXTgUMl7wXQBcdbWHgC0SS9tHMj5PE4B/SXdk4HBfmblBOkKpgsWoRoj1Z3QRIIMa6YbREEHwCjoAkKVXD42lV1tVpoiMlbctkF5BL1r6w19NSjTxj6UATpHuSBOTY0SWto9UGbp/NxNfId2RoaU9LbUnS0coVaC8wb4+65Y9q+wzBvtJN4yGGa+KHp94u+TxUyJd4l542M6TLoywdIKSoQO6ylhvS+07AHLdVVQGbq3sWPcr6Y5/C7Ru/BkID0h3ZMDAMXf1NJ6pm1nlGo3/W1ThYZCVV1ZVlhEdIp0wOn5J8uhk6XDCbOdyaJU5W19TImyTblAydEBXGeFFi0ocmHsAuOo+ZAK2kBNfLt0xUhkGrwFYeDlhBggHsfG3SWcUPNdtJaiygrw6oBcDxtukE0ZjyCs6oFt89dDOq61qMix9TUnsSQpKlg7oKiO9lTtDYLxHuiNNTI5ZVN3x4z3SISNNa/1BL9gsle7IBAFXRprP/ph0R2HTCb0YEfP+0g0qD4hsHNDZM1S6RTbB2uFknnSAyjobvwbhMOkV9CKlA7pKW29L7fHM1CTdkS7blraPVN2+/gEAP5LuyAARnDt2Np8zUzqkYJGucS9OzsHSBSof2MbhYOtrN1FctIAcW6+gHy4doLLuMOmAUfGwrSepVI7pgK7S0l1/foXD5m4AHumWdNi6tP0tHLoKjJ3SGRmYO8zJVdIRhYr1AnpxMqQDeoE7ZDGXAbDudWaC7PJ2AOTgdemGFCprWvZYueu3St8br6WVj7U0JaxX0IuUDugqLR7v0EoAh0p3pMnape0jVXes3wpi8ce/ZYIJn402L/y0dEch0uvnRcu6wU1l166S2DsAlEh3jESO7AZxAEAe7xbphlSSw169il4gLH4tY92tU6LSEUqGDuhqwnobz/4vgC+X7kgXE3/T5qXtI1W1bbwdjN9Id2SC4Xyru/58SzdbUcpl2NbdvVW2eDzmaOmG0TDMZumGsvLSzbB0Aw7Djq1DnUqTva8lvQSQlZ//Kvd0QFcTsiP0qRmOSa6Fyy7mEbCFkglXXZEmgNnxXAlA9v6/jFDAUzL4dekKpQoDT5/TFD9AukLlDoOPkm4YDRG/KN2wJUQJwM7HTBGRnfcsq7TZ+1rKr2JRcnRAVxMynCj7FkD7SXekyTVL20cKdD7wAhGHpDsywlgYaVqwQDpDqUKQdBwrBziVNcdIB4zKOH+XTgAAYrws3TAaBh0h3aCygy3dII4gvw+EkqMDuhpXT9PCcwDUSXeky21L20eqfJFXgfCYdEcmiOjWSEOtPsM5W3SVW/FiO5dAqyxYxCUA3iudMYrB8I6K56QjAMCx4Er+6NjSZdEqbWznrvz2fu6rfNABXY0pel3tXBheLd2RLjcubR+JurqSDplLAAxJt2Sgijx0u3REwdD5vHgR64BeoILT4u8GUCHdMYp/YA1Z8nOHnpEuSOGguS27K6Uj1OTMbdldCbJ1M06PXkEvYjqgq5QYIE6ab4PtfPzEGFy7tH2k4Ip1TxHQId2RGToz2lR3gXRFQdDnoBczG6+wqixg4ETphhSsWN4OAMZhWwd0Gk56bH391AQND3lOgKV7K3mJ/yndoOTogK5S6m2uuxrAadId6XL70vaRdvTvvgHAP6Q7MsGEW3qvW7i/dIfb6XPQi9q8OdfG9GuoABHh/dINoyHCU9IN/0Yw1v7sYyYd0F3P2tewd2u7/1XpCCVHB3Q1qnBD3cEMtEp3pKsQlraP9PbVPx8wDi4BkJRuycB0J8lr2dIz1G6h//GKW9LQSdINKstC7AXwQemM0TjkWDOgb1vlexWAlavhiO08waImjg2Ol25IwZqvQSVDB3T1Fhw6xWs8uB/AFOmWNBXM0vaRKjs2/IkI35TuyNCHo011i6QjlHIrW6+0qszV9CdOBDBDumM0zgBZNBwQw9ZhhXDsvBD7pDNUZuaHuJTY2luInpAOULJ0QFdvEY0HlwN4n3RHuhi4rZCWto80PFTaAtj5yJlxEVZFmmsPkc5wL13jXswc8KnSDSq7HPDp0g0pRKM3V9j27PG/SAekUNbfn7B1wFPjiPbFjwHgl+4YDRP9TbpBydIBXb1Jz/K6d4NwvXRHugjYQk68Wbojl2pW3tdPMJfBndNaBcHczaGQfs/JhG4SV9QIOKy6OaEnuAoIgT4u3ZCCjVer/1c6IBWjq1vci3CCdEJKTvJJ6QQlS98sq/94YfFpZezgHgAl0i1pKtil7SNVta17iEH3Sndk6MSe+LOLpSOUciMz7HxCukFlx5xlA4cDPF+6Y1TMf5ZOGIlhbL2CDnJwsnSDypiVe0AA6I/srnhWOkLJ0gFd/cfMimntBBwp3ZGuQl/aPlKJL7EEwFbpjkwQoa23pfYd0h2u48Y1Eyq7CDqgFwjHM3yOdENKhEelE0aKdJa9DKBXumM0THxysJ5tfJa9GsMbewd8SLojhT9jDQ1JRyhZOqArAEC0+exTGXDd1c1iWNo+0szQD3cysES6I0O+JJs7ubbWIx3iLjqhK3xgzrLdVdIRarKYmMnWAZ09TvJP0hFvRQzgj9IVKfiA2IelI1R6Ev2xUwGUS3eMhoh/L92g5OmArrC9qXY6w7kL7vt8YAIuL4al7SMF2jZ0MeP70h2ZIOC43reZBukOd9F70BVKHOOpk45QkxNsjL8PwMHSHaMhwgtbV02LSneMhhkPSzekREZXt7iMA7J1k0YwjA7oynUDmcqBJJnVAA6Q7kgXA7dVtm34pXSHGMe5GsAO6YxMMCEUXn72UdIdSrkJg86XblCTxZdKF6TCzJukG1LxEj8i3ZAaf/KN59orNwixIcJZ0hkpDMHxWbiKReWbDuhFLtqy4FMAXPemrxiXto8U6OzqZiK3XokuM0nnHg7VlkqHKOUi75vTmDhMOkJl5oDmnTPBdLZ0R2r0a+mCVLZuKX8SwE7pjhSqA/F+W+9nViPM3pN4PxizpTtS+Ft4JfVLRyh5OqAXsW0ttdXMuF26IwNFu7R9pOrW9WsZcOcqAsK7ogPmOukMpdzEgbNIukFlZiBZehEsve8VgEPepLUDOrooCeB30hmpUJL09hOXSBpeIN2QGrvz/ZzKOh3Qi5iXzVqAAtIdaSN8q6iXtu+DAE6CLgfQJ92SEcbyaHPde6UzlLLZvlsEMuOzc0Js65CnUgmxAXCldEYqRHiyu3Vqj3THWIj4F9INKZE5S78u7Tc/xKUE2DugE/1UOkHZQQf0ItXTsuAywH2P7SFgC5LxJukOm8xuW78FoC9Kd2TIy8A9m0MX+aRD7Ka7uBezEVsEzkzGYufJlKhMBWKxMwG8XbojFYdh/aNKKWksHl54uhNL1EpXqLH19MfPAFAt3ZFCJFzu/4t0hLKDDuhFqPv62oPAtEq6IwO6tD2FKt/hXwfwB+mODB0xJR7/snSE3XQXd7UPNov3fjtUbkGO3fuFMOhB6YbxbFvlfwWgv0t3pOTYuwGg2otAF0s3pMLgnyFEjnSHsoMO6EWGQyHjGfbcBWCqdEvadGl7ShQKOUTmUgAJ6ZaMEOojTQs+IJ2hlDvwkcH6mOtWQBWrQEPsRBBOkO4YQ7hni+9R6YiJYWtPJDDh/TVNe+ZLd6jRzWmKHwDwR6U7UjGgn0k3KHvogF5kehPPNQB8snRHBl7Rpe1jq2pd9xzAbdIdGTLkvnfBAAAgAElEQVREdFckVDtFOkQpVyBaLp2gJoZg+2tFP3pjEzbrMWDtgA4A7HiXSDeo0Q07fDUAj3RHConBhN/ePRZU3umAXkR6m86ez+CQdEcG2ACLdGn7+Kp8kRvBeEK6I0NvMwNmhXSEUi5xXE1j/IPSEWpsgfrY8QCfLt0xFgfJH0g3TFSk0/8ogFelO1Lj86sb+mqkK9SbzQlxOQGXSHekwowHt6+m3dIdyh46oBeJFxafVuaQcz8A923GpUvbJ4xCjwwTO5cDcMXVkJGY8bne5rqPSHfYRreIU6Nhh78q3aDGRoQbpBvGsSNQUfGQdMTEEQP4nnTFGMo8RFdIR6g3G+6PXQigUrojJcP3Sycou+iAXiRmlE/7CoCjpTsyoEvb01TV0fUXML4u3ZEhcsB37gh9aoZ0iE10NzA1KsIJwcb+M6Uz1OiC9fFTAXxIumNstPGZEA1KV6SFsUE6YSzMdM3Mpu3TpTvUXnsfrUY2v4/cMS1e/nPpCGUXHdCLQLhp4QkgLJPuyIAubc/QkD/2BQAvSndkhvYbTpR1SlfYRa+hqxTY3IhatvW+yuIVYkOGV0pnjIcN3yvdkK7wSv9fAGyW7hjDzJKkX+9Ft0S0L3YhgAOlO1Ii+u6Lq2lAOkPZRQf0Atddf36FIb4b9m6MkZoubc/YnNBPYgBdBvdOdpdGWhZYfd+mUnbgIwMHxS6TrlBvFuxLfJYZx0h3jInxYqTd/0fpjPQRA3YvCSbC0gOad86U7ih280NcavuGmg7jPukGZR8d0Aucxzt4M4C3S3dkQJe2T1J12/pHANwp3ZEpYtyxa2ntLOkOO+gid5UaMd04Z9nuKukOtdesxTwNZP/+AEx03xv3dLsOecydACx+ZjRPH0iWfkG6othF++JXAZgn3ZEa/b2n0/976QplHx3QC1i4acFHYfGulWPQpe1Z4mGnHuDXpDsyQ7MHy8wt0hVKucCspKdEn4BgiZKy+I0AbN/Je9ib5LukIzLV3ebfQky/ku4Yx+eqrk0cKh1RrGYs2TEDhOulO8bC5Nwq3aDspAN6gdq67OwqQ3Q3XHnpjW7Xpe3ZMau9axeIrpTumIRzIy0L/1s6QpwLv4pVnjFfMntZ/APSGcUuUB87HoSrpDvGQ4wfb/1a+b+kOybDIf62dMM4SjweZ5V0RLHylZRdD5t3bgft4vLy70hXKDvpgF6gSkucb8L+M/ijeQVOrFE6opBUt254EEQbpTsyRcy3hZefHZTukMSuXISq8sw4htcG67lCOqRYHbKYy4hoDdzw3srQN6QTJiuyy/9jAN3SHeP4RKAh9hnpiGITqO87ioHPS3eMifienhD1SWcoO9n/Q0SlLdpUdwEDtdIdGWCH+XJd2p59Q4N0NYAe6Y4MVRnHuV06QpJeQFcTdDAo3iodUaz6fPGvAnykdMf46JnuDt8j0hWTtoaGALJ+iTARVs9YskMfHZovITYEcxsAr3TKGJzksLH+c/f/t3fv8XHVdf7H35/vpE1m0pZeM6UgC4qwLj9AYdUF7xe8gj9BagvuwxtYdAWXS5K2uMp4+fWSaS0u7qoICsqtdFERLwj6Q5YFlXUBZRVXqtxLJklpC81MmmbOZ/8ouMBCm6ZJvudMXs9/oDzCnBchkznfc77n+0U8DNAbTN8n5+/jpvNjd4yMfbW48uofx65oRPNWX9lnrvbYHXvg//YuWfC+2BFABpxe7Og/NnbERFNsr73RpbNjdwyHe3JBVheHe7ampu1fllSN3bFTrr2bJ09O/ZZ7jWJutfpRmY6O3bEzJn2n7wstf4jdgfRigN5AXDIl4WJJWdzag6ntY2z2yrXflHRd7I4Rc31p4ycXviB2RhTcQsfwmWSXzDu7OjHfKxHMXfrEHDe/VNk4p+ouTClcGjtitDyyfNpGl9K/2J3bKW3t1eNjZzS6OR0DL3a3rtgdu2KJM9MJO5WFDxMMU9/SBX/vrrfG7hgBpraPk5wnp0vK5vfZNL2eJBf7RByuNsS9LoyjWfWc1h54hjfHDml4JW/yodyVJu0bO2U4TFpzf8kGYneMrrBGUj12xa6Y6WuzzqruE7ujYc33XPDkEkkpX4fDb3h0det/xK5AujFAbxB9S0/6S7kyus0OU9vHy8yV6x406dzYHSNlbsf0LVmQxa0DgfF21NaW6oWxIxrd3P7acklveurPKb+WtnlwIP+V2BGjrafc8kdJa2N3DMOs3CRdoUU+KXZIIyruX/1s2qe2S5J54O45dokBegPw0uubXH6ppHzslhFgavs4m9Xykn+WdEvsjj1wfqVjwYtiRwBp57L3FztqS2J3NKq5nbUPuHTO0/9Zuqf3+Jceu8Aej10xFhKFkqSh2B27Yq7XFqfXeB59lBXb+4+TbGnsjl1x6ZbuVfmfxe5A+jFAbwB9A22flvsrYneMAFPbI7BSKZHpVElZnebYGnJ+4YSc6g7sNl9WbK8x62SUze2svcHdL1Rmfg/ZlklDQ2tiV4yV3nLLvZJ/M3bHsLg+0dZRe3/sjEYx++yBg2T2TWXhvRjEBVMMCwP0jOtdMv9IybL5hjddyNT2OOYsX/sHd/tc7I6Rszf2Ll5weuwKIANM5l9lL+bRs/c5/Ue6+7WSJsduGTZX+eE1ez0WO2MshSR8VtK22B3DYfKL2hZvzeKaQamyz9LHZ+VyyfclZWEbu+/2rCzcFjsC2cAAPcM2lI4rSOFySVl8nukB1WsdsSMmsjn57i7JMrtQiZlW9C5dcFDsDiADciZdUezsf1fskKyb19F/RBLsBklTY7fshkoypeWLsSPG2qOr8w9Iysoz9pMsCevmdfQfETskq/Y9y/NDQ03XSXpx7JZhqFuo/0PsCGQHA/QMa9qW75J0cOyOEWBqewpY6WdDifspkrbHbhmhgrtd4vPn52KHABkwWW7/UuyonhQ7JKvmnN3/srrsRkkzY7fsFtey3pJtjZ0xHppzg5+R1Bu7Y5im1mXXt7VvPSx2SNbsX/KWodzAdyQdFbtlWNy/2b1y6m9jZyA7GKBnVN+S977Z3P4udseIMLU9NYor1/7a5V+I3TFSJj9q44F2zq6/EoB2zLa6bG5nfzY/OyKa21F7XciFm5S9wfn6qdvyX42dMV4eXDF9k8yzdKdyjln4advirYfHDsmKA8/w5lr/wDVunpFHBGxLYp7Z3XMQBwP0DNpUevd0l12sLCyI8b8xtT1ltvQ/cZ6ke2J3jJS7fbZ78fxDY3cAGRHc7Z+KndU1mu/MPhmGtvbq8S6/XvK9YrfsPj97/QWWieeyR0vlvsLFZrozdsdumG1J+GlbR/VVsUPSbk7JpzzRUv2e5O+I3TJ8fl5veUp37ApkCwP0DBoaaPlnSfvF7hgBpran0Isv+NG2YMkpkpLYLSPUnLNwqS9alMW1GIYni5fikG6uM4v71747/cxNWVhcKRK3YmdtqZn+RVJL7JrdZbLrK6tar4vdMe7WWT0xna5sfabNMuknLOb4/IrtT7SF/tpNkr0ldsvw2d2V1vw/xa5A9jBAz5i+JQuPlzybzxAytT21Zi1f93OZsjwN8mV9M7akfg9UIGWObZ7U/B97n9N/ZOyQtCm2e2uxo3al3Jcpm+dK20MSzoodEcuTq2VnbWDUYtLVxfbaJyXnsuzTzOnY+lJZ7heS/jp2y27wRPq4SjYUOwTZk8UPnQmrt3PhvET6WuyOEXogNDd1xo7A8wvNTUskPRS7Y8RMn+rtXJilD+/hc49dgMb1wiTYrW3t1bNVcs4J9NRgoPYrSQtit4yUu87fsLr597E7Ykpa8+dKuj92x24KMv98saP2PWa37NDWWXtfULhV0gGxW3aL2UW95fwtsTOQTXwYZ4RLpuBfM/ms2C0j4In7abNKlz8eOwTPb1bp8sfddVrsjj3QpOCX3lf6YOamou4aN1MwpprNtLqtv/azto6BF8WOiWa+59raq2cHhV9I+svYOXvg3sn1/HmxI2LrLdlWt7BIUhavcB7bPKn5rrmdtTfEDoll5hk+rdje/3Vzv0xSIXbPbrq/rhYWsMWIMUDPiI2LF3xUUoYWxXiGrzG1PRvaVq79kaTLY3fsgb9q3VZrwBPTLJ5fImtMeo0pubutvXbevmd5PnbPeGpbvPXw4v61n5tptaTm2D17IAmJnfrwGqvFDkmDnq6WG02W1ce3/sLdf1rsrH6x2O6tsWPG09yO2usmtdTuktmHYreMQGJmH+7rMtZbwogxQM+AypKTX+imlbE7RuiRppZti2NHYPiabfDvJe+J3TFS5ursWTz/1bE7Rhd30DFu8mZe2t5U+12xvbqw0ae9zzvn8dnF9uoFloRfSXp57J495dKXH12d/9fYHWnSNNRytmRZ3YPa5PqEW+33xY5qZh+5GK62c7cW53b0X+rym5S1Ke1PMX2puyt/U+wMZFtDf/A2Ai+VQlD9EklTY7eMgCfup8wofXdz7BAM37Tl39ko6czYHXsgWAiX9JTmT4kdAmTY/jJdWewfuKuts//djTZQn93pU4udtaX1MGm9dqz43RS7aRTcl1iexTKf5eE1VpMPLZSU2VkFJu0r6apiR/VnbYurR8fuGW3zSl6Y21ldbNvD7132fmX2qrTdnSvwHsSea6gP3EbUO3DPUkmvid0xQkxtz6g5K66+Uq7vxu4YMdeLwkD4fOwMIPv8UHP7Tlt/7Xdtnf0fnVfyrD0L+gxzlz4xZ25H/2dyXntgxwrtWdzb/DltN9NCptU+t8qqqf/p5mfH7hgFr7NEt87tqP2oEQbq80peKHZUz6hXa+vdtUJSdhfGc23NJeG9G0pWjZ2C7GOAnmI9585/qUmfjt0xQkxtzzq3j8uV2dkPLp3Ru2Th62N3AI3ApIPN7cv1/tojxY7aV9raq0fFbho+t73Pqb222FG9wodyD7ns05JmxK4aTW5a2t1VuD12R5r1dLV+xVzfit0xGlz+Nkt0a7Gj+stiR/WkQ0o+OXbT7tins7pvsb1/Wb2/9pCkf5Rr79hNe8y0aKLvnIDRk9EpJI3v3jPe3jyjddq/u3Ro7JYRcFd4R9uKK6+PHYI907t4wWkyfSV2x0iZdL8ntcPmdH0vc3eViu3VT8j0xdgdz3JFpVx4X+yI0VZcvPVQJeE3sTueZlBSFk6475P0fVf4/rSB5pvXX2DbYgf9WcnDnP6BVwXzE911wpNThBuU/bBSbjlWMlaT3IX9S95S66/dLOkVsVtG2UaXrjLXtyqrCr+MHfNc9j3L89ubau822ftdfoykXOym0WKyr3SX8x+L3YHG0QjPXDWk6a3T/l9GB+eS9DUG541h9sq1F/YtWXCipDfHbhkJl/ZXLl+W9NHYLcDw+c2S9Uo6OXbJLhwg6QxTcsYTzbWtc9urN7jZD1x2c0+55Y/jHTPzDJ82uaX6aikc6/214yXN3bFHaUN7KJds/4CUZ3A+DPeXbGDWWdUTmpp0u6R5sXtG0SyTPi7Tx4sd1QdN9gMlyXVhauHmmFOuZ3f2z8sl4e0yP267asdIKniD7Uri0i1TB1qyvG4PUogBego9uQJ1Vt/sTG1vICZ5d1OyKDcU7paUzW1eXIt6Fi+49skt5IAs8Hxr/pRqf+0FlpU1SExTXDpB8hNMrmJHtVdmt7vrdlf99uah+u0Pr9nrsdE8ZNu5W4saDEdb0Gvd9VpT7XCX5SbQtoT9iZJ3VVZP64sdkiUb1xQeKbZXT5DpJkmNuJ3gfi7/mIJ9rN5f217sqP7KXf8Wgm6ve/h1b2vzH1WyZLQPun/JW7Y9UT0kCeFwKXmVZK+R68UNPbHDtb7Jh05I1ewhNIQGv7CcPb2d75pqIf8bl/aP3TICHqS3zVqx9obYIRhdvUsWdEjqit0xcv5wU8vgoVnaUeCZU9xdKfl1zRT3ceE3VMqtb51+5qbpzZOab5Z0WOyiUbLJpfuC636Z7pP8Psl63MOmJOcDTUNJrR5ym5vqyWB9cpiUDNb3Ui5MySXJFLcwQ9IBJj/YTQdJOkgN9hz5bkrcdWLPqsJ3YodkVbGz/11yu0YT72ZVVaZ7LNEDCrrfEz0gWV9i9cdyiW0Mudzj9aDtklQfqNdyLbm8JCX1oWmm0GruM83CLMnbJNs/Me0v9xeadKAaaNr6MGzKWThqQ1fLf8UOQeOZaL+U0i/kz8vo4FySvsbgvDHN/mPyhb4XhfnK7D7Btu/2gebPSTojdslwWVDif77xkIrBuTSBbk2mwebzZ2yefWb/23KT7FZldU/gZ5ph0gw3HbHjj0/+XFuikEhJMJkS1XOS6olCziS5POz4q8QP4P+wT/WsyjM43wOVrtbvFTtqp0l+kVL0S3YcFOQ60k1H/s+1X1dQkAep7olU3/GFuUkm1XfcbA9PrSttpv+Zpu4NfYN8J7aZ2XsYnGOssIp7ivR1LniJpE/E7hghprY3MFu3rl735BTtWLwqk0z6WOXckzJzJzKRD8VueDb39DWNBhuaVI/d8Hz6zm99NMmFt0iqxG5BSrh/o1JuWR47oxFUyvmvS3Zu7A5kyna5L+juyt8UOwSNiwF6injQckmTYneMgAfpw1maPozdN3flurvNLMPT3JULSX1Z7IjhsiRsj93wbBbUkAP0oZRfeOhd0bI+J3+H5I/HbkFc5vp25YHCR1ixffRUyvkVkn8+dgcyoS7pA5VVrdfGDkFjY4CeEo8tnr+fpGNjd4yI20VMbZ8YZjXXPyfpt7E7Rs7e0bNk/oGxK4bDTakboMtDqgeyI5ULnr7v9bNsKLfeYRbeLWkgdgti8RunbMufrHWW2hkfWVUpt37KZefF7kCqudxOq5QLV8YOQeNjgJ4SSbDTlM3FNR4K+Vx77AiMDyutG0zcFkka9RVgx4nJwimxI4bD3FP3OIG7N+TAoCkDA3RJ6u7K3yT39yrDj5pgxH4uLxzPatFjp6ec/6yM6e54TnUzO6WyKn9x7BBMDAzQU8Ld3h27YQTcFRbNKl3OtMsJpLjyqttM/qXYHSNlrhNiNwxL8Gh71z4fS+Nd/VEw6Em6ZgbY8z/eUFnVep3k75HEQG2icN02GAbeXlll/bFTGl2lK79cO7a5zepFaIy+bW56b3dX/huxQzBxMEBPgcq5JxUlvSR2x25zu6htxZXXx87A+BtsqS2V9KfYHSN0UG/nwnmxI3bFPGx5+p/T8MCpmRryDvrkpiRVFx7MfafT2Cvl1u+bM0ifGPwnUv4tm1bO3LLrr8VoqJQLX3TTfEm12C2IzLVVHo7t6Sp8O3YKJhYG6GmQ1F+t7G3xwdT2CWxe6bpqkD6mdIwbd5sHf1Xshl2pq/6ME/I0/ILwxBtyQFjbOjVVA3QfxnPm3ataf+AWjmPhuIb2vakDhWO5cz7+eroK33bXmyT1xW5BNBtC8DdUVrX8JHYIJh4G6CkQLGRtf1umtkOzVqy9waRLY3eMRDBP/Xsul8s9a1eE+NdCzKwhd2ooNKVs6r7t/A76U3q6Wm5U8FdLemiMizD+LqtsyZ/IM+fx9Kwq/DzJhaMk/13sFowvl+4YGtIrHu1q/VXsFkxMDNDTIPF9YifsFqa240nBkzMlPRK7Y7e5Uv+ea9o2+KwLYPF/Xbt5Qw7QH16jASk9g3R3G/ZK7ZWVU+6um/+NS3eMZRPGjbtbqVLOv18XWmp+Jieq3hUt65PWwislrY3dgvFh0jXm+dduXFPI3rkNGkb8Mz5I0tTYAbvhoZzqHbEjkA4zV67b4mZnxu7YXYlseuyGXXl4zbRNevozxp6CO+hum2I3jA1zSY/FrnhK2M2t1Pq6Wjd4a/51ktj+J9sGJL2vZ1X+M+xznh69JdtaKRcWSjpbUroWlMRoGpLsk93l/HweK0FsDNDTIGRnyxxXWDRz5ToWq8GftS2/6l/clakFVMyysPiPuaQNf/5jCn5bJwoN/N731AzQXbv/KMGTg4iTXf53YvG4LOrxoDexx3J6VcqFNYnsjZIeiN2C0eXSw4nsjZVyfhkXx5AGKTjlg5IsDBYkuS5majuei+UmnS4pO3dXs/Kee/qJYApOGZoSezB2w1gxt42xG55mw66/5Ln1lFu/nJMfrezusjDhmOvfhoZ0RM/Kwm2xW7BzveX8LYNh4HBzfSt2C0aL/bApGXpZbzl/S+wS4CkM0FPApftjNwzDI035bazajuc0Z9llj7o8Mz8fGXnPSdLdT/1NCsbngxumTl4fO2KsuKVoinuiPfo+byi33jEYBo5w+SWjlISx4Sat6p6SfwPPu2bHppUzt3SvKrzfpRMlpenCHnaLPy7z0yrllmM3rJ7Gav1IFQboKRBylvoVQt31kRml7zbkAlEYHW0rrv66SzfE7hiOYP7b2A3D47956u/ib7Nmf1DJGvf5S/e0nGh7rT7wm11/2c5tWjlzS0+59UOSHyfTo6MRhlG1Sebv7i4XOhr6fdXAesqFaxIl/0es/ZBBfmNIwmGVrtYLmdKONGKAngKTavU7JdVjdzwv18VtK9f+KHYG0i9pSj4qKe2LqyTbzX8dO2I4LGlK0ZTX5PbYBWPJFVLyXKnfs/n8GaN2MbRSbv1+cxg8RNLlo/Wa2FN+Y66uwytdrd+LXYI901ue0r1j7YfwVkl/jN2DXeqT/COVcuGtj67Op+R3PvC/MUBPgb3WrHtMUopOxJ+Bqe0YtrmfX3efTP8Qu2NnTPrF3svX9cbuGI7u1ZPvkVSJ3SFJbvaD2A1jyZTcFbthB7txtF/xwRXTN1XKhb91C2+R/J7Rfn0MW9Xkp1fKhbdu+EKBvesbSE+55YZJQ/lDzfxzUmbWOJlIhuT6UnNu8KBKufUi7poj7Rigp4VZGq+kuyucytR27I7Z65MLXPpF7I7n5boudsLwmZv8x7ErJNUS5Ud94JgmuVy4M3aDJMnH7rOgp6vlxsqWwuGSzpasgVfkTyHXbYnCS7vLrf/E4KAxPbzGat1drZ/O1XWwu18qKYndBEnSTxWSIyqrCmc8uGJ6dhazxYTGAD0lJg/Uvy6pGrvjWVi1HbvN1q2rBwsf0m7u5TxOtnlu0qWxI3aL6+rYCZJ9q6/LnohdMZY2rMw/6NIdkTMeqUxp+dmYHuFC214pF9bIhw6S7CKxr/NYq8jt1MqU/Gt6yy33xo7B2NvwhcJDPataP5goOVLyn8TumcB+IbM3V8qFN1dWTrl7118OpAcD9JR4cpr7ZbE7nuaRScp1xo5ANs1efuXv5Voeu+N/cV02Z9llmVowa9aUwo2KO83dLQlfjHj8cWPSJVGPb/51lWxc7rpVVk3tqZTzH1EuHCz51yVtH4/jTiCDJq0eDAMHV1blLx6v/69Ij97ylLsq5dZjTPZ6BurjZ8eFVj+uUi4cVenK/zR2DzASDNBTpCmXW6Z03EV3Vzh1+oormAqEEZudT1bY07YJS4FakqTwosEu/LZkg5J9KdbxTfp29+rm1O80MRqac4OXKd62Sf2hXv/H8T5oZUXLnyrl1lPkdvCTd9QZqO8Zl3RtzsJh3eVC+6aVM3mUYILrLudvrpRbj3HX0dqxlgePOIw+l+yHMntzT7lwZKXc+v3YQcCeiL9zD56hb/GCJW6RBxGui+esXHtq1AY0hL4lC17u0q2SJsVucfdPta28+vOxO0Zi37O2zNzeNGm9pBnjfOjNdfND+rpaN4zzcaMpttdOkflF431ck3+2u9x63ngf99nmLa7tV6/738l0iqTZsXsyZEjS1QrJCqbTYmfaFm893JLc6ZKfLKkQuyfTXFtldkWwcP6jXc0sgImGwQA9Zbw0f3LfQPhXSa+MlPA7b0le2VZatzXS8dFg+pYsXOzyFVEjTL+a3Zy8ykrrBqN27IFiR+3Dkl88nsc0sw93d+W/MZ7HjM+t2FG9QbI3j+NBfz91IP/S9RfYtnE85k7tX/KWgerAAnf/uKSXx+5JsW0m+4bnrFxZ0fKn2DHIjpln+LRJ+epCuf5esr+K3ZMppv+Q/MK6Clc2+voomJgYoKdQ3yfn7+P18CtJc8f50E9YolfO7lrLVUiMGi+VQt/APddKOjZSQiUkTX89q+vyhyMdf5S4FTtq10o6bnwOp5WVVYUl43KslNlx4lz7/3IdOQ6Hq+bkr9lQbo29QN3zmttZfYXLTpX7iRr/WRypZKY7PdElOR+6YsPqaX2xe5BlbnM7Bl7r0smSnyhpZuyidPJ7JF2TS5ou37C6+fexa4CxxAA9pfo657/CQ7he43cy1O9mb29bftUt43Q8TCAbSscVJg20/lDy143rgV2bLdjbZi+/6pfjetwxMqfkU0J/7SZJfz22R7KvVsotH5vI20HNXfrEHN+eu1Gmw8fwMImb5vd0Fb49hscYNQee4c2P56tvD25/69I7JbXEbhpnvTJd7pZc0rNyyq9jx6DxHFLyyX391bdIdpJk75R8r9hNEblLd5rsO8HCNUxhx0TCAD3Fes6d/1JLwg2S5ozxoTZJdsKcFVf9bIyPgwmst/NdUz3Xco25HTNOh+xT0FvnLFub2juTIzF36RNzfCh3raSjxuDlByV1Vsr5f5zIg/OnzFj82F6Tk+Z10pj8zG6X2wcrq/JXjMFrj7kd35v8eyS9R/I3qmEH6/Zbl/8gyH7Y3dpyq0rGtnQYHyVvmts/8CqXv03S2yQdrsY/b++TdKOZ/bju9R/3lqd0xw4CYmj0N3rmdf/D/ANyQ+FKjdEz6SbdXa/r+GJ57R/H4vWBp/PS65v6Btq6JDtrjA/170ldJzXqz/X+JW+pbq1+xcw+MIov+xtL/NTu1a3/PoqvmX0lD8X+gSWSf0qjNwjtTpR8qLc85fpRer2o5pW8UN9aPcZlbzHz12f6eVrTo3L90sxvVAg/7F6Rvz92EiBJs8/s3zvXFN4g87+R6Wi5DpfUFLtrDz0k6RaT35YE/7eefOvdbEkIMEDPBF+0aNLGmVvOc+kcjd4J4qCZddUG6stesGZdbZReExiWvnMXvskT/7KkF4kwCEwAAAVtSURBVI/yS29z05o5zcl5WV4Qbrjmttde7/Lz93Aa9r1yK1WmtFzFidHza+sYeJFZ8nm55kvKjfBlhiT/ZnNue/uDK6Y37DaWbeduLWowHB2CH+5uh0k6TNILlbpzDn/cze4Krttl+mUY0i83fKHwUOwqYDiK7d5qGni5zF8h+SFudohcL1F6V4a/z1x3JrK7TMldTcHufKSrkPG1YYCxkbIPS+zMY4vn75dY+IxL79PIt63aZq4rPGjFnOVr/zCafcDuuK/0wZbWbQOLzP1sSX+xhy835NIVddl5e6+46v5RyMsQt7bFtaNU1/vM9E4N73tZcffrg8Il3atabmY6+/AV22sHuPS3IfjxvuMOVtjFvzIk6T8lW1vfnlzad37ro+OQmTqzO31qsNqhqvuhFuwv5drbXPu4aZ6keRqbKfKD2jFltsdcf3LpXsnuDa576831/+pZNqUyBscE4il5aOvfdoB5/a8kO8CC/sJdL5C0n0z7yTVXY3fu/5hkG8z1iIfkYZPdm7jWKyTrm/Kt924oWXWMjgs0HAboGfTo0vlzckk4WaaFJh2pXQ/WE8luk/Rthaar5iy7bEKeICKdfNGiSRtnbX6ne3iP3I+Vafow/9Xtku6Q6arEwpXFZVdysi1pvyWbZ2wban6ZBb3AE99LZtNcCkHJRsl6EoU7esotDTn1f7zNWPzYXs31/Mvc9EIzn+PyqfJQNSVbEg9bLPj6Sdvzv354jTFLaRf2PWvLzKHJYW+vNxWlZKqZTU5kebOkRYm1WFA+SWyyyVtlttXMtyeJtlvwHVuCJva45DU362uy0FcdrFU2nz9jc+T/LCBdSh722fbEjMGhyTNzlsxILJlh9TBDwadJksumhienzbv7NMmCmf78PkoS3xwsbEvct5hsS86SzUkuPNa0raXC7zlg9DBAz7j7Sh9sKdQGjrCglwQlszyxWZIHV9hkpr7E9Z+Wr/+Gfc2RBV4qhb5t9xzoib/UQtjP3Kcn0gyTmuTabGaPuXxjYn7P4IDfweMZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADsxH8D0oEwmN3diTAAAAAASUVORK5CYII=\";\n export default img;","var img = \"data:image/gif;base64,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\";\n export default img;","/*\r\n * Copyright (C) 2024 Xibo Signage Ltd\r\n *\r\n * Xibo - Digital Signage - https://www.xibosignage.com\r\n *\r\n * This file is part of Xibo.\r\n *\r\n * Xibo is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Lesser General Public License as published by\r\n * the Free Software Foundation, either version 3 of the License, or\r\n * any later version.\r\n *\r\n * Xibo is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Lesser General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Lesser General Public License\r\n * along with Xibo. If not, see <http://www.gnu.org/licenses/>.\r\n */\r\nimport Layout, { getLayout, getXlf, initRenderingDOM } from './Modules/Layout';\r\nimport { platform } from './Modules/Platform';\r\nimport {\r\n ILayout, initialLayout, InputLayoutType, OptionsType,\r\n} from './Types/Layout';\r\nimport { initialXlr, IXlr } from './Types/XLR';\r\nimport SplashScreen, {PreviewSplashElement} from './Modules/SplashScreen';\r\nimport {getIndexByLayoutId} from './Modules/Generators/Generators';\r\n\r\nexport default function XiboLayoutRenderer(\r\n inputLayouts: InputLayoutType[],\r\n options?: OptionsType,\r\n) {\r\n const props = {\r\n inputLayouts,\r\n options,\r\n }\r\n\r\n const xlrObject: IXlr = {\r\n ...initialXlr,\r\n };\r\n\r\n\r\n xlrObject.bootstrap = function() {\r\n // Place to set configurations and initialize required props\r\n const self = this;\r\n self.inputLayouts = !Array.isArray(props.inputLayouts) ?\r\n [props.inputLayouts] : props.inputLayouts;\r\n self.config = JSON.parse(JSON.stringify({...platform, ...props.options}));\r\n\r\n // Prepare rendering DOM\r\n const previewCanvas = document.querySelector('#preview_canvas');\r\n\r\n initRenderingDOM(previewCanvas);\r\n\r\n // Prepare splash screen\r\n const splashScreen = SplashScreen(\r\n document.querySelector('.player-preview'),\r\n self.config,\r\n );\r\n\r\n splashScreen.show();\r\n };\r\n xlrObject.init = function() {\r\n return new Promise<IXlr>((resolve) => {\r\n const self = this;\r\n\r\n // Check if only have splash screen from inputLayouts\r\n if (self.inputLayouts.length === 1 && self.inputLayouts[0].layoutId === 0) {\r\n resolve(self);\r\n } else {\r\n self.prepareLayouts().then((xlr) => {\r\n resolve(xlr);\r\n });\r\n }\r\n });\r\n };\r\n\r\n xlrObject.playSchedules = function(xlr: IXlr) {\r\n // Check if there's a current layout\r\n if (xlr.currentLayout !== undefined) {\r\n const $splashScreen = document.querySelector('.preview-splash') as PreviewSplashElement;\r\n if ($splashScreen && $splashScreen.style.display === 'block') {\r\n $splashScreen?.hide();\r\n }\r\n\r\n xlr.currentLayout.emitter.emit('start', xlr.currentLayout);\r\n xlr.currentLayout.run();\r\n }\r\n };\r\n\r\n xlrObject.updateLoop = function(inputLayouts: InputLayoutType[]) {\r\n this.updateLayouts(inputLayouts);\r\n };\r\n\r\n xlrObject.updateLayouts = async function(inputLayouts: InputLayoutType[]) {\r\n /**\r\n * @TODO\r\n * Case 1: If currentLayout in inputLayouts and in the same sequence,\r\n * Then, continue playing currentLayout.\r\n * Check nextLayout in inputLayouts. If in inputLayouts and same sequence, then don't change.\r\n * If not in inputLayouts, then replace and prepare nextLayout.\r\n *\r\n * Case 2: If currentLayout in inputLayouts but not in the same sequence,\r\n * Then, replace loop, prepare layouts and start currentLayout\r\n *\r\n * Case 3: If currentLayout not in inputLayouts,\r\n * Then, replace everything and start from first layout in sequence.\r\n */\r\n\r\n this.inputLayouts = inputLayouts;\r\n /** Case 1: When currentLayout is not in inputLayouts\r\n * Then, replace everything and start from first layout\r\n */\r\n if (inputLayouts.filter((inputLayout) => inputLayout.layoutId === this.currentLayout?.layoutId).length === 0) {\r\n // Unset currentLayout, nextLayout and layouts\r\n this.layouts = [];\r\n this.currentLayout = undefined;\r\n this.nextLayout = undefined;\r\n\r\n const xlr = await this.prepareLayouts();\r\n this.playSchedules(xlr);\r\n } else {\r\n /** Case 2: When currentLayout is in inputLayouts, then continue playing\r\n * Also check for nextLayout if in inputLayouts and same sequence, then don't change and continue playing.\r\n * If not in inputLayouts, then replace and prepare nextLayout.\r\n */\r\n\r\n // 2.1 We don't have to do anything for currentLayout\r\n // 2.2 Check for nextLayout\r\n // Get nextLayout index\r\n const currLayoutIndex = getIndexByLayoutId(inputLayouts, this.currentLayout?.layoutId).index as number;\r\n const nxtLayoutIndex = getIndexByLayoutId(inputLayouts, this.nextLayout?.layoutId).index as number;\r\n const tempOldNxtLayout = this.layouts[nxtLayoutIndex];\r\n let newNxtLayoutIndex = currLayoutIndex + 1;\r\n\r\n if (nxtLayoutIndex !== newNxtLayoutIndex) {\r\n // Delete old nextLayout\r\n delete this.layouts[nxtLayoutIndex];\r\n\r\n if (Boolean(this.layouts[newNxtLayoutIndex])) {\r\n this.nextLayout = this.layouts[newNxtLayoutIndex];\r\n this.layouts[newNxtLayoutIndex] = this.nextLayout;\r\n } else {\r\n // Check if newNxtLayoutIndex is still within inputLayouts\r\n if ((newNxtLayoutIndex + 1) > inputLayouts.length) {\r\n // Goes back to first layout in the sequence\r\n newNxtLayoutIndex = 0;\r\n }\r\n\r\n if (Boolean(inputLayouts[newNxtLayoutIndex])) {\r\n const tempNxtLayout = {...initialLayout, ...inputLayouts[newNxtLayoutIndex]};\r\n this.nextLayout = await this.prepareLayoutXlf(tempNxtLayout);\r\n this.layouts[newNxtLayoutIndex] = this.nextLayout;\r\n }\r\n\r\n // Move old nextLayout to its index\r\n let hasOldNxtLayout = inputLayouts\r\n .filter((_layout) => _layout.layoutId === tempOldNxtLayout?.layoutId);\r\n\r\n if (hasOldNxtLayout.length === 1) {\r\n const oldNxtLayoutIndex =\r\n getIndexByLayoutId(inputLayouts, hasOldNxtLayout[0].layoutId).index as number;\r\n this.layouts[oldNxtLayoutIndex] = tempOldNxtLayout;\r\n }\r\n }\r\n } else {\r\n // Check if newNxtLayout is not the same with nextLayout\r\n // Then, replace nextLayout with new one\r\n if (inputLayouts[nxtLayoutIndex].layoutId !== this.nextLayout?.layoutId) {\r\n const tempNewNxtLayout = {...initialLayout, ...inputLayouts[nxtLayoutIndex]};\r\n this.nextLayout = await this.prepareLayoutXlf(tempNewNxtLayout);\r\n this.layouts[nxtLayoutIndex] = this.nextLayout;\r\n }\r\n\r\n // Remove old nextLayout if it's not in inputLayouts\r\n if (tempOldNxtLayout?.index && Boolean(this.layouts[tempOldNxtLayout?.index])) {\r\n if (inputLayouts.filter((_layout) => _layout.layoutId === tempOldNxtLayout?.layoutId).length === 0) {\r\n delete this.layouts[tempOldNxtLayout?.index];\r\n }\r\n }\r\n }\r\n }\r\n };\r\n\r\n xlrObject.prepareLayouts = async function() {\r\n const self = this;\r\n // Get layouts\r\n const xlrLayouts = getLayout({xlr: self});\r\n\r\n console.debug('prepareLayouts::xlrLayouts', xlrLayouts);\r\n\r\n self.currentLayoutId = xlrLayouts.current?.layoutId as ILayout['layoutId'];\r\n\r\n const layoutsXlf = () => {\r\n let xlf = [];\r\n\r\n xlf.push(xlrLayouts.current);\r\n\r\n if (xlrLayouts.current?.layoutId !== xlrLayouts.next?.layoutId) {\r\n xlf.push(xlrLayouts.next);\r\n }\r\n\r\n return xlf.reduce((coll: Promise<ILayout>[], item) => {\r\n return [\r\n ...coll,\r\n self.prepareLayoutXlf(item),\r\n ];\r\n }, []);\r\n };\r\n const layouts = await Promise.all<Array<Promise<ILayout>>>(layoutsXlf());\r\n console.debug('prepareLayouts::layouts', layouts);\r\n console.debug('prepareLayouts::xlr>layouts', self.layouts);\r\n\r\n return new Promise<IXlr>((resolve) => {\r\n layouts.map((layoutItem) => {\r\n if (!Boolean(self.layouts[layoutItem.index])) {\r\n self.layouts[layoutItem.index] = layoutItem;\r\n }\r\n });\r\n self.currentLayoutIndex = xlrLayouts.currentLayoutIndex;\r\n self.currentLayout = self.layouts[self.currentLayoutIndex];\r\n\r\n if (Boolean(layouts[1])) {\r\n self.nextLayout = layouts[1];\r\n } else {\r\n // Use current layout as next layout if only one layout is available\r\n self.nextLayout = self.layouts[0];\r\n }\r\n\r\n self.layouts[self.currentLayoutIndex] = self.currentLayout;\r\n\r\n resolve(self);\r\n });\r\n };\r\n\r\n xlrObject.prepareLayoutXlf = async function(inputLayout: ILayout) {\r\n const self = this;\r\n // Compose layout props first\r\n let newOptions: OptionsType = Object.assign({}, platform);\r\n\r\n newOptions = {\r\n ...newOptions,\r\n ...props.options,\r\n };\r\n\r\n if (self.config.platform ==='CMS' &&\r\n inputLayout && Boolean(inputLayout.layoutId)\r\n ) {\r\n newOptions.xlfUrl =\r\n newOptions.xlfUrl.replace(':layoutId', String(inputLayout.layoutId));\r\n } else if (self.config.platform === 'chromeOS') {\r\n newOptions.xlfUrl = inputLayout.path as string;\r\n }\r\n\r\n let layoutXlf: string;\r\n let layoutXlfNode: Document | null;\r\n if (inputLayout && inputLayout.layoutNode === null) {\r\n layoutXlf = await getXlf(newOptions);\r\n\r\n const parser = new window.DOMParser();\r\n layoutXlfNode = parser.parseFromString(layoutXlf as string, 'text/xml');\r\n } else {\r\n layoutXlfNode = inputLayout && inputLayout.layoutNode;\r\n }\r\n\r\n return new Promise<ILayout>((resolve) => {\r\n const xlrLayoutObj = initialLayout;\r\n\r\n xlrLayoutObj.id = Number(inputLayout.layoutId);\r\n xlrLayoutObj.layoutId = Number(inputLayout.layoutId);\r\n xlrLayoutObj.options = newOptions;\r\n xlrLayoutObj.index = getIndexByLayoutId(this.inputLayouts, xlrLayoutObj.layoutId).index as number;\r\n\r\n resolve(Layout(layoutXlfNode, newOptions, self, xlrLayoutObj));\r\n });\r\n };\r\n\r\n xlrObject.bootstrap();\r\n\r\n return xlrObject;\r\n}\r\n","/*\r\n * Copyright (C) 2024 Xibo Signage Ltd\r\n *\r\n * Xibo - Digital Signage - https://www.xibosignage.com\r\n *\r\n * This file is part of Xibo.\r\n *\r\n * Xibo is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Lesser General Public License as published by\r\n * the Free Software Foundation, either version 3 of the License, or\r\n * any later version.\r\n *\r\n * Xibo is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Lesser General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Lesser General Public License\r\n * along with Xibo. If not, see <http://www.gnu.org/licenses/>.\r\n */\r\nimport './splash-screen.css';\r\nimport xiboLogoImg from './img/logo.png';\r\nimport loaderImg from './img/loader.gif';\r\nimport {OptionsType} from '../../Types/Layout';\r\n\r\nexport interface ISplashScreen {\r\n init: () => void;\r\n show: () => void;\r\n hide: () => void;\r\n}\r\n\r\nexport interface PreviewSplashElement extends HTMLDivElement {\r\n hide: () => void;\r\n}\r\n\r\nexport default function SplashScreen($parent: Element | null, config?: OptionsType): ISplashScreen {\r\n const $previewSplash = document.createElement('div') as PreviewSplashElement;\r\n const $previewLoader = document.createElement('div');\r\n const $previewLoaderCaption = document.createElement('div');\r\n const $defaultNoLayout = document.createElement('div');\r\n\r\n const splashScreenObj = {\r\n init() {\r\n $previewSplash.classList.add('preview-splash');\r\n\r\n // Don't show Xibo logo on CMS Preview\r\n if (config && config.platform !== 'CMS') {\r\n $previewSplash.style.setProperty(\r\n 'background-image',\r\n `url(${xiboLogoImg})`,\r\n );\r\n $previewSplash.style.setProperty(\r\n 'background-size',\r\n '200px 120px',\r\n );\r\n $previewSplash.style.setProperty(\r\n 'background-position',\r\n 'calc(100% - 50px) calc(100% - 30px)',\r\n );\r\n }\r\n\r\n $previewSplash.constructor.prototype.hide = () => {\r\n this.hide();\r\n };\r\n\r\n $previewLoader.classList.add('preview-loader');\r\n $previewLoaderCaption.classList.add('preview-loaderCaption');\r\n\r\n // Show loader bar and text on CMS Preview\r\n if (config && config.platform === 'CMS') {\r\n $previewLoader.style.setProperty(\r\n 'background-image',\r\n `url(${loaderImg})`,\r\n );\r\n $previewLoaderCaption.innerHTML = '<p>Loading Layout...</p>';\r\n }\r\n\r\n $previewSplash.insertBefore($previewLoader, $previewSplash.lastElementChild);\r\n $previewSplash.insertBefore($previewLoaderCaption, null);\r\n\r\n this.hide();\r\n },\r\n show() {\r\n if ($parent) {\r\n $parent.insertBefore($previewSplash, $parent.firstElementChild);\r\n $previewSplash.style.setProperty('display', 'block');\r\n }\r\n },\r\n hide() {\r\n $previewSplash.style.setProperty('display', 'none');\r\n },\r\n };\r\n\r\n splashScreenObj.init();\r\n\r\n return splashScreenObj;\r\n}\r\n"],"names":["createNanoEvents","emit","event","_len","arguments","length","args","Array","_key","i","callbacks","this","events","apply","on","cb","_this$events","_this","push","_this$events$event","filter","platform","getResourceUrl","xlfUrl","layoutBackgroundDownloadUrl","layoutPreviewUrl","libraryDownloadUrl","loaderUrl","idCounter","inPreview","appHost","initialLayout","id","layoutId","sw","sh","xw","xh","zIndex","scaleFactor","sWidth","sHeight","offsetX","offsetY","bgColor","bgImage","bgId","containerName","layoutNode","regionMaxZIndex","ready","regionObjects","drawer","allExpired","regions","actions","options","done","allEnded","path","prepareLayout","parseXlf","run","callback","regionExpired","end","regionEnded","stopAllMedia","Promise","resolve","resetLayout","emitter","index","nextId","getMediaId","_ref","mediaType","mediaId","capitalizeStr","inputStr","String","charAt","toUpperCase","substring","getDataBlob","_x","_getDataBlob","_asyncToGenerator","_regeneratorRuntime","mark","_callee","src","wrap","_context","prev","next","abrupt","fetch","mode","then","res","blob","rej","reader","FileReader","onloadend","result","onerror","readAsDataURL","stop","preloadMediaBlob","_x2","_x3","_preloadMediaBlob","_callee2","type","data","_context2","sent","Blob","arrayBuffer","audioFileType","filename","filenameArr","split","URL","createObjectURL","fetchJSON","_x4","_fetchJSON","_callee3","url","_context3","json","err","console","debug","str","validAudioTypes","mp3","wav","ogg","Boolean","getIndexByLayoutId","layoutsInput","layoutIndexes","reduce","a","b","indx","Number","_objectSpread","initialRegion","layout","regionId","xml","mediaObjects","mediaObjectsActions","currentMedia","complete","ending","ended","oneMedia","oldMedia","undefined","curMedia","nxtMedia","currentMediaIndex","totalMediaObjects","prepareRegion","playNextMedia","transitionNodes","finished","exitTransition","exitTransitionComplete","prepareMediaObjects","reset","initialMedia","region","html","iframe","iframeName","render","attachedAudio","singlePlay","timeoutId","setTimeout","checkIframeStatus","loadIframeOnRun","tempSrc","schemaVersion","duration","useDuration","fileId","uri","divWidth","divHeight","loop","init","defaultTrans","trans","keyframes","display","timing","fadeOutElem","opacity","fill","flyInElem","keyframeOptions","direction","flyInKeyframes","flyInTiming","from","to","flyOutElem","flyOutKeyframes","flyOutTiming","transitionElement","transition","fadeIn","fadeOut","flyIn","flyOut","defaultIn","defaultOut","flyTransitionKeyframes","params","opacityAttr","source","top","concat","height","left","width","Media","xlr","props","mediaTimer","mediaTimeCount","mediaObject","startMediaTimer","media","setInterval","$videoMedia","document","getElementById","onloadstart","onloadeddata","readyState","oncanplay","videoPlayPromise","play","error","muted","onplaying","ondurationchange","onended","_media$emitter","VideoMedia","$audioMedia","$playBtn","remove","audioPlayPromise","_$audioMedia$parentNo","name","createElement","classList","add","textContent","addEventListener","parentNode","insertBefore","nextSibling","AudioMedia","clearInterval","_self$xml","_self$xml2","_self$xml3","_self$xml4","_self$xml5","self","getAttribute","parseInt","$mediaIframe","mediaOptions","getElementsByTagName","_i","_Array$from","_mediaOptions","children","_i2","_Array$from2","mediaOption","nodeName","toLowerCase","showfullscreen","scrolling","style","cssText","$mediaId","$media","Audio","className","resourceUrlParams","config","regionOptions","isGlobalContent","isImageOrVideo","tmpUrl","resourceUrl","replace","composeResourceUrlByPlatform","_options$config","_options$config2","_options$config3","hardwareKey","cmsKey","composeResourceUrl","align","valign","preload","mute","scaletype","objectFit","playsInline","autoplay","regex","RegExp","exec","transInDuration","transinduration","fadeInTrans","animate","transInDirection","transindirection","defaultTransInOptions","transIn","transInName","showCurrentMedia","_ref2","isCMS","getNewMedia","setProperty","t0","t1","t2","t3","t4","call","t5","innerHTML","appendChild","$region","lastElementChild","ELayoutType","playAgainClickHandle","ev","preventDefault","history","go","getXlf","_getXlf","_callee4","layoutOptions","apiHost","fetchOptions","_context4","window","location","origin","headers","text","getLayout","activeLayout","_currentLayout2","_currentLayout","_nextLayout","_params$xlr","inputLayouts","currentLayout","nextLayout","currLayoutIndx","currentLayoutIndex","hasLayout","nextLayoutIndex","nextLayoutTemp","layouts","current","Layout","$layout","prepareLayouts","parent","playSchedules","layoutObject","$layoutContainer","$splashScreen","_layout$layoutNode","_layout$layoutNode2","_layout$layoutNode3","_layout$layoutNode4","_layout$layoutNode5","_layout$layoutNode6","$screen","outline","offsetWidth","offsetHeight","firstElementChild","Math","min","abs","position","indexOf","bgImageUrl","composeBgUrlByPlatform","backgroundImage","backgroundRepeat","backgroundSize","backgroundPosition","backgroundColor","currentLayoutId","layoutRegions","forEach","regionXml","regionObj","regionObject","_self$xml6","_regionOptions","regionOption","round","regionMediaItems","mediaXml","mediaObj","nextMediaIndex","newMedia","transOutDuration","transOutDirection","transoutduration","transoutdirection","transOutName","defaultTransOutOptions","transOut","hideOldMedia","$oldMedia","oldMediaAnimate","removeOldMedia","_oldMediaAnimate","effect","updateTiming","isDone","_self$curMedia","_self$curMedia2","_self$curMedia3","_self$curMedia4","Region","_step","_iterator","_createForOfIteratorHelper","s","n","value","e","f","$end","$preview","firstChild","removeChild","_step2","_iterator2","_ref3","j","exports","initialXlr","bootstrap","prepareLayoutXlf","inputLayout","updateLayouts","updateLoop","img","xlrObject","isArray","JSON","parse","stringify","_targetContainer","previewPlayer","previewScreen","endPlay","playAgainLink","previewCanvas","querySelector","removeEventListener","body","$parent","$previewSplash","$previewLoader","$previewLoaderCaption","splashScreenObj","xiboLogoImg","constructor","prototype","hide","loaderImg","show","SplashScreen","_this$currentLayout","_this$nextLayout","currLayoutIndex","nxtLayoutIndex","tempOldNxtLayout","newNxtLayoutIndex","tempNxtLayout","hasOldNxtLayout","oldNxtLayoutIndex","_this$nextLayout2","tempNewNxtLayout","_this2","_this2$currentLayout","_layout","_xlrLayouts$current","xlrLayouts","layoutsXlf","_xlrLayouts$current2","_xlrLayouts$next","xlf","coll","item","_toConsumableArray","all","map","layoutItem","newOptions","layoutXlf","layoutXlfNode","parser","_this3","Object","assign","DOMParser","parseFromString","xlrLayoutObj"],"mappings":"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","x_google_ignoreList":[0]}
|
|
1
|
+
{"version":3,"file":"xibo-layout-renderer.min.js","sources":["../node_modules/nanoevents/index.js","../../src/Modules/Platform/Platform.ts","../../src/Types/Layout/Layout.types.ts","../../src/Modules/Generators/Generators.ts","../../src/Types/Region/Region.types.ts","../../src/Types/Media/Media.types.ts","../../src/Modules/Transitions/Transitions.ts","../../src/Modules/Media/Media.ts","../../src/Modules/Media/VideoMedia.ts","../../src/Modules/Media/AudioMedia.ts","../../src/Modules/ActionController/ActionController.ts","../../src/Types/XLR/XLR.types.ts","../../src/Modules/Layout/Layout.ts","../../src/Modules/Region/Region.ts","../src/Modules/SplashScreen/img/logo.png","../src/Modules/SplashScreen/img/loader.gif","../../src/xibo-layout-renderer.ts","../../src/Modules/SplashScreen/SplashScreen.ts"],"sourcesContent":["export let createNanoEvents = () => ({\n emit(event, ...args) {\n for (\n let i = 0,\n callbacks = this.events[event] || [],\n length = callbacks.length;\n i < length;\n i++\n ) {\n callbacks[i](...args)\n }\n },\n events: {},\n on(event, cb) {\n ;(this.events[event] ||= []).push(cb)\n return () => {\n this.events[event] = this.events[event]?.filter(i => cb !== i)\n }\n }\n})\n","/*\r\n * Copyright (C) 2024 Xibo Signage Ltd\r\n *\r\n * Xibo - Digital Signage - https://www.xibosignage.com\r\n *\r\n * This file is part of Xibo.\r\n *\r\n * Xibo is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Lesser General Public License as published by\r\n * the Free Software Foundation, either version 3 of the License, or\r\n * any later version.\r\n *\r\n * Xibo is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Lesser General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Lesser General Public License\r\n * along with Xibo. If not, see <http://www.gnu.org/licenses/>.\r\n */\r\nimport {OptionsType} from \"../../Types/Layout\";\r\n\r\nconst RESOURCE_URL = '/playlist/widget/resource/:regionId/:id';\r\nconst XLF_URL = '/layout/xlf/:layoutId';\r\nconst LAYOUT_BACKGROUND_DOWNLOAD_URL = '/layout/background/:id';\r\nconst LAYOUT_PREVIEW_URL = '/layout/preview/[layoutCode]';\r\nconst LIBRARY_DOWNLOAD_URL = '/library/download/:id';\r\nconst LOADER_URL = '/theme/default/img/loader.gif';\r\n\r\nexport const platform: OptionsType = {\r\n getResourceUrl: RESOURCE_URL,\r\n xlfUrl: XLF_URL,\r\n layoutBackgroundDownloadUrl: LAYOUT_BACKGROUND_DOWNLOAD_URL,\r\n layoutPreviewUrl: LAYOUT_PREVIEW_URL,\r\n libraryDownloadUrl: LIBRARY_DOWNLOAD_URL,\r\n loaderUrl: LOADER_URL,\r\n idCounter: 0,\r\n inPreview: true,\r\n appHost: null,\r\n platform: 'CMS',\r\n};\r\n","/*\r\n * Copyright (C) 2024 Xibo Signage Ltd\r\n *\r\n * Xibo - Digital Signage - https://www.xibosignage.com\r\n *\r\n * This file is part of Xibo.\r\n *\r\n * Xibo is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Lesser General Public License as published by\r\n * the Free Software Foundation, either version 3 of the License, or\r\n * any later version.\r\n *\r\n * Xibo is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Lesser General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Lesser General Public License\r\n * along with Xibo. If not, see <http://www.gnu.org/licenses/>.\r\n */\r\nimport {Emitter, Unsubscribe} from 'nanoevents';\r\nimport {IRegion} from '../Region';\r\nimport {platform} from '../../Modules/Platform';\r\nimport {ILayoutEvents} from '../../Modules/Layout';\r\nimport {IXlr} from '../XLR';\r\nimport InteractiveActions, { Action } from '../../Modules/ActionController';\r\n\r\nexport type InputLayoutType = {\r\n layoutId: number | null;\r\n path?: string;\r\n};\r\n\r\nexport type OptionsType = {\r\n xlfUrl: string;\r\n getResourceUrl: string;\r\n layoutBackgroundDownloadUrl: string;\r\n layoutPreviewUrl: string;\r\n libraryDownloadUrl: string;\r\n loaderUrl: string;\r\n idCounter: number;\r\n inPreview: boolean;\r\n appHost?: string | null;\r\n platform: 'CMS' | 'chromeOS';\r\n config?: {\r\n cmsUrl: string | null;\r\n schemaVersion: number;\r\n cmsKey: string | null;\r\n hardwareKey: string | null;\r\n };\r\n previewTranslations?: {\r\n [k: string]: any;\r\n }\r\n};\r\n\r\nexport interface ILayout {\r\n id: number | null;\r\n layoutId: number | null;\r\n sw: number | null;\r\n sh: number | null;\r\n xw: number | null;\r\n xh: number | null;\r\n zIndex: number | null;\r\n scaleFactor: number;\r\n sWidth: number;\r\n sHeight: number;\r\n offsetX: number;\r\n offsetY: number;\r\n bgColor: string;\r\n bgImage: string;\r\n bgId: string;\r\n containerName: string;\r\n layoutNode: Document | null;\r\n regionMaxZIndex: number;\r\n ready: boolean;\r\n regionObjects: IRegion[];\r\n drawer: Element | null;\r\n allExpired: boolean;\r\n regions: IRegion[];\r\n actions: Action[];\r\n options: OptionsType;\r\n done: boolean;\r\n allEnded: boolean;\r\n path?: string;\r\n prepareLayout(): void;\r\n parseXlf(): void;\r\n run(): void;\r\n emitter: Emitter<ILayoutEvents>;\r\n on<E extends keyof ILayoutEvents>(event: E, callback: ILayoutEvents[E]): Unsubscribe;\r\n regionExpired(): void;\r\n end(): void;\r\n regionEnded(): void;\r\n stopAllMedia(): Promise<void>;\r\n resetLayout(): Promise<void>;\r\n index: number;\r\n actionController: InteractiveActions | undefined;\r\n}\r\n\r\nexport const initialLayout: ILayout = {\r\n id: null,\r\n layoutId: null,\r\n sw: 0,\r\n sh: 0,\r\n xw: 0,\r\n xh: 0,\r\n zIndex: 0,\r\n scaleFactor: 1,\r\n sWidth: 0,\r\n sHeight: 0,\r\n offsetX: 0,\r\n offsetY: 0,\r\n bgColor: '',\r\n bgImage: '',\r\n bgId: '',\r\n containerName: '',\r\n layoutNode: null,\r\n regionMaxZIndex: 0,\r\n ready: false,\r\n regionObjects: [],\r\n drawer: null,\r\n allExpired: false,\r\n regions: [],\r\n actions: [],\r\n options: platform,\r\n done: false,\r\n allEnded: false,\r\n path: '',\r\n prepareLayout() {\r\n },\r\n parseXlf() {\r\n },\r\n run() {\r\n },\r\n on<E extends keyof ILayoutEvents>(event: E, callback: ILayoutEvents[E]): Unsubscribe {\r\n return <Unsubscribe>{};\r\n },\r\n regionExpired() {\r\n },\r\n end() {\r\n },\r\n regionEnded() {\r\n },\r\n stopAllMedia() {\r\n return Promise.resolve();\r\n },\r\n resetLayout() {\r\n return Promise.resolve();\r\n },\r\n emitter: <Emitter<ILayoutEvents>>{},\r\n index: -1,\r\n actionController: undefined,\r\n};\r\n\r\nexport type GetLayoutParamType = {\r\n xlr: IXlr;\r\n moveNext?: boolean;\r\n}\r\n\r\nexport type GetLayoutType = {\r\n currentLayoutIndex: number;\r\n inputLayouts: InputLayoutType[];\r\n current: ILayout | undefined;\r\n next: ILayout | undefined;\r\n}\r\n","/*\r\n * Copyright (C) 2024 Xibo Signage Ltd\r\n *\r\n * Xibo - Digital Signage - https://www.xibosignage.com\r\n *\r\n * This file is part of Xibo.\r\n *\r\n * Xibo is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Lesser General Public License as published by\r\n * the Free Software Foundation, either version 3 of the License, or\r\n * any later version.\r\n *\r\n * Xibo is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Lesser General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Lesser General Public License\r\n * along with Xibo. If not, see <http://www.gnu.org/licenses/>.\r\n */\r\nimport { IMedia } from '../../Types/Media';\r\nimport {InputLayoutType, OptionsType} from '../../Types/Layout';\r\n\r\nexport function nextId(options: { idCounter: number; }) {\r\n if (options.idCounter > 500) {\r\n options.idCounter = 0;\r\n }\r\n\r\n options.idCounter = options.idCounter + 1;\r\n return options.idCounter;\r\n}\r\n\r\nexport const getMediaId = ({mediaType, containerName}: IMedia) => {\r\n let mediaId = containerName;\r\n\r\n if (mediaType === 'video') {\r\n mediaId = mediaId + '-vid';\r\n } else if (mediaType === 'audio') {\r\n mediaId = mediaId + '-aud';\r\n }\r\n\r\n return mediaId;\r\n};\r\n\r\nexport const capitalizeStr = (inputStr: string) => {\r\n if (inputStr === null) {\r\n return '';\r\n }\r\n\r\n return String(inputStr).charAt(0).toUpperCase() + String(inputStr).substring(1);\r\n};\r\n\r\nexport async function getDataBlob(src: string) {\r\n return fetch(src, {mode: 'no-cors'})\r\n .then((res) => res.blob())\r\n .then((blob) => new Promise((res, rej) => {\r\n const reader = new FileReader();\r\n\r\n reader.onloadend = () => res(reader.result);\r\n reader.onerror = rej;\r\n reader.readAsDataURL(blob);\r\n }));\r\n}\r\n\r\nexport async function preloadMediaBlob(src: string, type: 'video' | 'audio' | 'image') {\r\n const res = await fetch(src, {mode: 'no-cors'});\r\n let blob: Blob | MediaSource = new Blob();\r\n\r\n if (type === 'image') {\r\n blob = new Blob()\r\n } else if (type === 'video') {\r\n blob = await res.blob();\r\n } else if (type === 'audio') {\r\n const data = await res.arrayBuffer();\r\n blob = new Blob([data], { type: audioFileType(getFileExt(src)) })\r\n }\r\n\r\n return URL.createObjectURL(blob);\r\n}\r\n\r\nexport async function fetchJSON(url: string) {\r\n return fetch(url)\r\n .then(res => res.json())\r\n .catch(err => {\r\n console.debug(err);\r\n });\r\n}\r\n\r\nexport async function fetchText(url: string): Promise<string> {\r\n return fetch(url)\r\n .then(res => res.text())\r\n .then((responseText) => {\r\n if (String(responseText).length > 0) {\r\n return responseText;\r\n } else {\r\n return '';\r\n }\r\n })\r\n .catch(err => {\r\n console.debug(err);\r\n return err?.message;\r\n });\r\n}\r\n\r\nexport function getFileExt(filename: string) {\r\n const filenameArr = String(filename).split('.');\r\n\r\n return filenameArr[filenameArr.length - 1];\r\n}\r\n\r\nexport function audioFileType(str: string) {\r\n const validAudioTypes = {\r\n 'mp3': 'audio/mp3',\r\n 'wav': 'audio/wav',\r\n 'ogg': 'audio/ogg',\r\n };\r\n\r\n if (Boolean(validAudioTypes[str as 'mp3' | 'wav' | 'ogg'])) {\r\n return validAudioTypes[str as 'mp3' | 'wav' | 'ogg'];\r\n }\r\n\r\n return undefined;\r\n}\r\n\r\nexport function composeResourceUrlByPlatform(options: OptionsType, params: any) {\r\n let resourceUrl = params.regionOptions.getResourceUrl\r\n .replace(\":regionId\", params.regionId)\r\n .replace(\":id\", params.mediaId) +\r\n '?preview=1&layoutPreview=1';\r\n\r\n if (options.platform === 'chromeOS') {\r\n const resourceEndpoint = '/required-files/resource/';\r\n\r\n if (!params.isGlobalContent && params.isImageOrVideo) {\r\n resourceUrl = resourceEndpoint + params.fileId + '?saveAs=' + params.uri;\r\n }\r\n } else if (!Boolean(params['mediaType'])) {\r\n resourceUrl += '&scale_override=' + params.scaleFactor;\r\n }\r\n\r\n return resourceUrl;\r\n}\r\n\r\nexport function composeResourceUrl(options: OptionsType, params: any) {\r\n const schemaVersion = (options) && options.config?.schemaVersion;\r\n const hardwareKey = (options) && options.config?.hardwareKey;\r\n const serverKey = (options) && options.config?.cmsKey;\r\n\r\n return '/pwa/getResource' +\r\n '?v=' + schemaVersion +\r\n '&serverKey=' + serverKey +\r\n '&hardwareKey=' + hardwareKey +\r\n '&layoutId=' + params.layoutId +\r\n '®ionId=' + params.regionId +\r\n '&mediaId=' + params.mediaId;\r\n}\r\n\r\nexport function composeVideoUrl(params: any) {\r\n return '/xmds.php?file=' + params.uri;\r\n}\r\n\r\nexport function composeBgUrlByPlatform(\r\n platform: OptionsType['platform'],\r\n params: any\r\n) {\r\n let bgImageUrl = params.layoutBackgroundDownloadUrl.replace(\":id\", (params.layout.id as unknown) as string) +\r\n '?preview=1&width=' + params.layout.sWidth +\r\n '&height=' + params.layout.sHeight +\r\n '&dynamic&proportional=0';\r\n\r\n if (platform === 'chromeOS') {\r\n bgImageUrl = '/required-files/resource/' + params.layout.id +\r\n '?saveAs=' + params.layout.bgImage;\r\n }\r\n\r\n return bgImageUrl;\r\n}\r\n\r\ntype LayoutIndexType = {\r\n [k: string]: InputLayoutType & {\r\n index: number;\r\n }\r\n}\r\n\r\nexport function getIndexByLayoutId(layoutsInput: InputLayoutType[], layoutId?: number | null) {\r\n let layoutIndexes = layoutsInput.reduce((a: LayoutIndexType, b, indx) => {\r\n a[Number(b.layoutId)] = {\r\n ...b,\r\n index: indx\r\n };\r\n\r\n return a;\r\n }, {});\r\n\r\n if (layoutId === null || !layoutId) {\r\n return layoutIndexes;\r\n }\r\n\r\n if (Boolean(layoutIndexes[layoutId])) {\r\n return layoutIndexes[layoutId];\r\n }\r\n\r\n // Defaults to 0\r\n return {index: 0};\r\n}\r\n\r\nexport function isEmpty(input: any) {\r\n return !Boolean(input) || String(input).length === 0;\r\n}\r\n\r\nexport const splashScreenLayoutObj: InputLayoutType = {\r\n layoutId: 0,\r\n path: '',\r\n};\r\n\r\nexport function splashScreenDOM() {\r\n const mediaItem = document.querySelector('.media--item');\r\n const newImg = document.createElement('img');\r\n\r\n newImg.src = new URL('./logo.png', import.meta.url).href;\r\n\r\n if (mediaItem !== null) {\r\n mediaItem.insertBefore(newImg, mediaItem.lastElementChild);\r\n }\r\n\r\n return newImg;\r\n}\r\n\r\nexport function getAllAttributes(elem: Element) {\r\n if (!elem || elem === null) {\r\n return {};\r\n }\r\n\r\n return elem.getAttributeNames()\r\n .reduce((obj, name) => ({\r\n ...obj,\r\n [name]: {\r\n value: elem.getAttribute(name),\r\n },\r\n }), <{[k: string]: any}>{});\r\n}\r\n","/*\r\n * Copyright (C) 2024 Xibo Signage Ltd\r\n *\r\n * Xibo - Digital Signage - https://www.xibosignage.com\r\n *\r\n * This file is part of Xibo.\r\n *\r\n * Xibo is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Lesser General Public License as published by\r\n * the Free Software Foundation, either version 3 of the License, or\r\n * any later version.\r\n *\r\n * Xibo is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Lesser General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Lesser General Public License\r\n * along with Xibo. If not, see <http://www.gnu.org/licenses/>.\r\n */\r\nimport { DefaultEvents, Emitter, Unsubscribe } from 'nanoevents';\r\nimport {ILayout, initialLayout} from '../Layout';\r\nimport {IMedia} from '../Media';\r\n\r\nexport interface IRegionEvents {\r\n start: (layout: IRegion) => void;\r\n end: (layout: IRegion) => void;\r\n}\r\n\r\nexport interface IRegion {\r\n layout: ILayout;\r\n id: string;\r\n regionId: string;\r\n uniqueId: string;\r\n xml: null | Element;\r\n mediaObjects: IMedia[];\r\n mediaObjectsActions: IMedia[];\r\n currentMedia: number;\r\n complete: boolean;\r\n containerName: string;\r\n ending: boolean;\r\n ended: boolean;\r\n oneMedia: boolean;\r\n oldMedia: IMedia | undefined;\r\n curMedia: IMedia | undefined;\r\n nxtMedia: IMedia | undefined;\r\n currentMediaIndex: number;\r\n totalMediaObjects: number;\r\n ready: boolean;\r\n options: {\r\n [k: string]: any;\r\n };\r\n sWidth: number;\r\n sHeight: number;\r\n offsetX: number;\r\n offsetY: number;\r\n zIndex: number;\r\n index: number;\r\n emitter?: Emitter<DefaultEvents>;\r\n prepareRegion(): void;\r\n playNextMedia(): void;\r\n playPreviousMedia(): void;\r\n transitionNodes(oldMedia: IMedia | undefined, newMedia: IMedia | undefined): void;\r\n finished(): void;\r\n run(): void;\r\n end(): void;\r\n exitTransition(): void;\r\n exitTransitionComplete(): void;\r\n on<E extends keyof IRegionEvents>(event: E, callback: IRegionEvents[E]): Unsubscribe;\r\n prepareMediaObjects(): void;\r\n reset(): void;\r\n}\r\n\r\nexport const initialRegion: IRegion = {\r\n layout: initialLayout,\r\n id: '',\r\n regionId: '',\r\n uniqueId: '',\r\n xml: null,\r\n mediaObjects: [],\r\n mediaObjectsActions: [],\r\n currentMedia: -1,\r\n complete: false,\r\n containerName: '',\r\n ending: false,\r\n ended: false,\r\n oneMedia: false,\r\n oldMedia: undefined,\r\n curMedia: undefined,\r\n nxtMedia: undefined,\r\n currentMediaIndex: 0,\r\n totalMediaObjects: 0,\r\n ready: false,\r\n options: {},\r\n sWidth: 0,\r\n sHeight: 0,\r\n offsetX: 0,\r\n offsetY: 0,\r\n zIndex: 0,\r\n index: -1,\r\n prepareRegion() {\r\n },\r\n playNextMedia() {\r\n },\r\n playPreviousMedia() {\r\n },\r\n transitionNodes() {\r\n },\r\n finished() {\r\n },\r\n run() {\r\n },\r\n end() {\r\n },\r\n exitTransition() {},\r\n exitTransitionComplete() {},\r\n on<E extends keyof IRegionEvents>(event: E, callback: IRegionEvents[E]): Unsubscribe {\r\n return <Unsubscribe>{};\r\n },\r\n prepareMediaObjects() {\r\n },\r\n reset() {\r\n }\r\n};\r\n","/*\r\n * Copyright (C) 2024 Xibo Signage Ltd\r\n *\r\n * Xibo - Digital Signage - https://www.xibosignage.com\r\n *\r\n * This file is part of Xibo.\r\n *\r\n * Xibo is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Lesser General Public License as published by\r\n * the Free Software Foundation, either version 3 of the License, or\r\n * any later version.\r\n *\r\n * Xibo is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Lesser General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Lesser General Public License\r\n * along with Xibo. If not, see <http://www.gnu.org/licenses/>.\r\n */\r\nimport {Emitter, Unsubscribe} from 'nanoevents';\r\nimport { IMediaEvents } from '../../Modules/Media/Media';\r\nimport {initialRegion, IRegion} from '../Region';\r\nimport {OptionsType} from '../Layout';\r\n\r\nexport interface IMedia {\r\n checkIframeStatus: boolean;\r\n run(): void;\r\n divHeight: number;\r\n type: string;\r\n timeoutId: ReturnType<typeof setTimeout>;\r\n divWidth: number;\r\n tempSrc: string;\r\n duration: number;\r\n iframeName: string;\r\n loadIframeOnRun: boolean;\r\n xml: Element | null;\r\n containerName: string;\r\n ready: boolean;\r\n loop: boolean;\r\n options: OptionsType & {\r\n [k: string]: any\r\n };\r\n useDuration: boolean;\r\n html: HTMLElement | null;\r\n id: string;\r\n mediaId: string;\r\n iframe: HTMLIFrameElement | null;\r\n render: string;\r\n attachedAudio: boolean;\r\n on<E extends keyof IMediaEvents>(event: E, callback: IMediaEvents[E]): Unsubscribe;\r\n init(): void;\r\n schemaVersion: string;\r\n index: number;\r\n mediaType: string;\r\n finished: boolean;\r\n uri: string;\r\n url: string | null;\r\n singlePlay: boolean;\r\n stop(): Promise<void>;\r\n idCounter: number;\r\n region: IRegion;\r\n fileId: string;\r\n emitter: Emitter<IMediaEvents>;\r\n}\r\n\r\nexport const initialMedia: IMedia = {\r\n region: initialRegion,\r\n xml: null,\r\n id: '',\r\n mediaId: '',\r\n index: 0,\r\n idCounter: 0,\r\n containerName: '',\r\n html: null,\r\n iframe: null,\r\n iframeName: '',\r\n mediaType: '',\r\n render: 'html',\r\n attachedAudio: false,\r\n singlePlay: false,\r\n timeoutId: setTimeout(() => {}, 0),\r\n ready: true,\r\n checkIframeStatus: false,\r\n loadIframeOnRun: false,\r\n tempSrc: '',\r\n finished: false,\r\n schemaVersion: '1',\r\n type: '',\r\n duration: 0,\r\n useDuration: Boolean(0),\r\n fileId: '',\r\n uri: '',\r\n options: <OptionsType>{},\r\n divWidth: 0,\r\n divHeight: 0,\r\n url: null,\r\n loop: false,\r\n run() {},\r\n init() {},\r\n stop() {\r\n return Promise.resolve();\r\n },\r\n on<E extends keyof IMediaEvents>(event: E, callback: IMediaEvents[E]): Unsubscribe {\r\n return <Unsubscribe>{};\r\n },\r\n emitter: <Emitter<IMediaEvents>>{},\r\n}\r\n","/*\n * Copyright (C) 2024 Xibo Signage Ltd\n *\n * Xibo - Digital Signage - https://www.xibosignage.com\n *\n * This file is part of Xibo.\n *\n * Xibo is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Lesser General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * any later version.\n *\n * Xibo is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * along with Xibo. If not, see <http://www.gnu.org/licenses/>.\n */\nexport const defaultTrans = (duration: number, trans: 'in' | 'out') => {\n const defaultKeyframes = [\n { display: trans === 'in' ? 'none' : 'block' },\n { display: trans === 'out' ? 'none' : 'block' },\n ];\n const defaultTiming: number | KeyframeAnimationOptions | undefined = {\n duration,\n };\n\n return {\n keyframes: defaultKeyframes,\n timing: defaultTiming,\n };\n};\n\nexport const fadeInElem = (duration: number) => {\n const fadeInKeyframes = [\n { opacity: 0 },\n { opacity: 1 },\n ];\n const fadeInTiming: number | KeyframeAnimationOptions | undefined = {\n duration,\n fill: 'forwards',\n };\n\n return {\n keyframes: fadeInKeyframes,\n timing: fadeInTiming,\n }\n};\n\nexport const fadeOutElem = (duration: number) => {\n const fadeOutKeyframes = [\n { opacity: 1 },\n { opacity: 0, zIndex: -1 },\n ];\n const fadeOutTiming: number | KeyframeAnimationOptions | undefined = {\n duration,\n fill: 'forwards',\n };\n\n return {\n keyframes: fadeOutKeyframes,\n timing: fadeOutTiming,\n }\n};\n\nexport type KeyframeOptionsType = {\n from: {\n [k: string]: any,\n },\n to: {\n [k: string]: any,\n },\n}\n\nexport const flyInElem = (duration: number, keyframeOptions: KeyframeOptionsType | undefined, direction?: string) => {\n const flyInKeyframes = [\n {opacity: 0},\n {opacity: 1, zIndex: 1},\n ];\n const flyInTiming: number | KeyframeAnimationOptions | undefined = {\n duration,\n fill: 'forwards',\n };\n\n if (keyframeOptions && Boolean(keyframeOptions.from)) {\n flyInKeyframes[0] = {...keyframeOptions.from, ...flyInKeyframes[0]};\n }\n\n if (keyframeOptions && Boolean(keyframeOptions.to)) {\n flyInKeyframes[1] = {...keyframeOptions.to, ...flyInKeyframes[1]};\n }\n\n return {\n keyframes: flyInKeyframes,\n timing: flyInTiming,\n };\n};\n\nexport const flyOutElem = (duration: number, keyframeOptions: KeyframeOptionsType | undefined, direction?: string) => {\n const flyOutKeyframes: Keyframe[] = [\n {opacity: 1},\n {opacity: 0, zIndex: -1},\n ];\n const flyOutTiming: number | KeyframeAnimationOptions | undefined = {\n duration,\n fill: 'forwards',\n };\n\n if (keyframeOptions && Boolean(keyframeOptions.from)) {\n flyOutKeyframes[0] = {...keyframeOptions.from, ...flyOutKeyframes[0]};\n }\n\n if (keyframeOptions && Boolean(keyframeOptions.to)) {\n flyOutKeyframes[1] = {...keyframeOptions.to, ...flyOutKeyframes[1]};\n }\n\n return {\n keyframes: flyOutKeyframes,\n timing: flyOutTiming,\n };\n};\n\nexport type TransitionNameType = 'fadeIn' | 'fadeOut' | 'flyIn' | 'flyOut' | 'defaultIn' | 'defaultOut';\n\nexport type TransitionElementOptions = {\n duration: number;\n keyframes?: KeyframeOptionsType;\n direction?: string;\n};\n\nexport const transitionElement = (transition: TransitionNameType, options: TransitionElementOptions) => {\n const transitions = {\n fadeIn: fadeInElem(options.duration),\n fadeOut: fadeOutElem(options.duration),\n flyIn: flyInElem(options.duration, options.keyframes, options.direction),\n flyOut: flyOutElem(options.duration, options.keyframes, options.direction),\n defaultIn: defaultTrans(options.duration, 'in'),\n defaultOut: defaultTrans(options.duration, 'out'),\n };\n\n return transitions[transition];\n};\n\nexport type compassPoints = 'N' | 'NE' | 'E' | 'SE' | 'S' | 'SW' | 'W' | 'NW';\n\nexport type flyTransitionParams = {\n trans: 'in' | 'out';\n direction: compassPoints;\n height: string | number;\n width: string | number;\n};\n\nexport const flyTransitionKeyframes = (params: flyTransitionParams): KeyframeOptionsType => {\n const keyframes = {\n from: {},\n to: {},\n };\n const opacityAttr = (source: 'from' | 'to') => {\n if (source === 'from') {\n return params.trans === 'in' ? 0 : 1;\n }\n \n return params.trans === 'out' ? 1 : 0;\n };\n\n switch (params.direction) {\n case 'N':\n keyframes.from = {\n opacity: opacityAttr('from'),\n top: params.trans === 'in' ? `${params.height}px` : 0,\n };\n keyframes.to = {\n opacity: opacityAttr('to'),\n top: params.trans === 'in' ? 0 : `-${params.height}px`,\n };\n break;\n case 'NE':\n keyframes.from = {\n opacity: opacityAttr('from'),\n top: params.trans === 'in' ? `${params.height}px` : 0,\n left: params.trans === 'in' ? `-${params.width}px` : 0,\n };\n keyframes.to = {\n opacity: opacityAttr('to'),\n top: params.trans === 'in' ? 0 : `-${params.height}px`,\n left: params.trans === 'in' ? 0 : `${params.width}px`,\n };\n break;\n case 'E':\n keyframes.from = {\n opacity: opacityAttr('from'),\n left: params.trans === 'in' ? `-${params.width}px` : 0,\n };\n keyframes.to = {\n opacity: opacityAttr('to'),\n left: params.trans === 'in' ? 0 : `${params.width}px`,\n };\n break;\n case 'SE':\n keyframes.from = {\n opacity: opacityAttr('from'),\n top: params.trans === 'in' ? `-${params.height}px` : 0,\n left: params.trans === 'in' ? `-${params.width}px` : 0,\n };\n keyframes.to = {\n opacity: opacityAttr('to'),\n top: params.trans === 'in' ? 0 : `${params.height}px`,\n left: params.trans === 'in' ? 0 : `${params.width}px`,\n };\n break;\n case 'S':\n keyframes.from = {\n opacity: opacityAttr('from'),\n top: params.trans === 'in' ? `-${params.height}px` : 0,\n };\n keyframes.to = {\n opacity: opacityAttr('to'),\n top: params.trans === 'in' ? 0 : `${params.height}px`,\n };\n break;\n case 'SW':\n keyframes.from = {\n opacity: opacityAttr('from'),\n top: params.trans === 'in' ? `-${params.height}px` : 0,\n left: params.trans === 'in' ? `${params.width}px` : 0,\n };\n keyframes.to = {\n opacity: opacityAttr('to'),\n top: params.trans === 'in' ? 0 : `${params.height}px`,\n left: params.trans === 'in' ? 0 : `-${params.width}px`,\n };\n break;\n case 'W':\n keyframes.from = {\n opacity: opacityAttr('from'),\n left: params.trans === 'in' ? `${params.width}px` : 0,\n };\n keyframes.to = {\n opacity: opacityAttr('to'),\n left: params.trans === 'in' ? 0 : `-${params.width}px`,\n };\n break;\n case 'NW':\n keyframes.from = {\n opacity: opacityAttr('from'),\n top: params.trans === 'in' ? `${params.height}px` : 0,\n left: params.trans === 'in' ? `${params.width}px` : 0,\n };\n keyframes.to = {\n opacity: opacityAttr('to'),\n top: params.trans === 'in' ? 0 : `-${params.height}px`,\n left: params.trans === 'in' ? 0 : `-${params.width}px`,\n };\n break;\n default:\n keyframes.from = {\n opacity: opacityAttr('from'),\n top: params.trans === 'in' ? `${params.height}px` : 0,\n };\n keyframes.to = {\n opacity: opacityAttr('to'),\n top: params.trans === 'in' ? 0 : `-${params.height}px`,\n };\n break;\n }\n\n return keyframes;\n};\n","/*\r\n * Copyright (C) 2024 Xibo Signage Ltd\r\n *\r\n * Xibo - Digital Signage - https://www.xibosignage.com\r\n *\r\n * This file is part of Xibo.\r\n *\r\n * Xibo is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Lesser General Public License as published by\r\n * the Free Software Foundation, either version 3 of the License, or\r\n * any later version.\r\n *\r\n * Xibo is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Lesser General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Lesser General Public License\r\n * along with Xibo. If not, see <http://www.gnu.org/licenses/>.\r\n */\r\nimport { createNanoEvents } from 'nanoevents';\r\nimport { OptionsType } from '../../Types/Layout';\r\nimport { IRegion } from '../../Types/Region';\r\nimport { IMedia, initialMedia } from '../../Types/Media';\r\nimport { fetchJSON, getMediaId, nextId, preloadMediaBlob } from '../Generators';\r\nimport { TransitionElementOptions, compassPoints, flyTransitionKeyframes, transitionElement } from '../Transitions';\r\nimport VideoMedia from './VideoMedia';\r\nimport AudioMedia from './AudioMedia';\r\nimport {composeResourceUrl, composeResourceUrlByPlatform, composeVideoUrl, fetchText, getDataBlob} from '../Generators/Generators';\r\nimport {IXlr} from '../../Types/XLR';\r\n\r\nexport interface IMediaEvents {\r\n start: (media: IMedia) => void;\r\n end: (media: IMedia) => void;\r\n}\r\n\r\nexport default function Media(\r\n region: IRegion,\r\n mediaId: string,\r\n xml: Element,\r\n options: OptionsType,\r\n xlr: IXlr,\r\n) {\r\n const props = {\r\n region: region,\r\n mediaId: mediaId,\r\n xml: xml,\r\n options: options,\r\n };\r\n let mediaTimer: string | number | NodeJS.Timeout | null | undefined = null;\r\n let mediaTimeCount = 0;\r\n const emitter = createNanoEvents<IMediaEvents>();\r\n const mediaObject: IMedia = {\r\n ...initialMedia,\r\n ...props,\r\n };\r\n const startMediaTimer = (media: IMedia) => {\r\n mediaTimer = setInterval(() => {\r\n mediaTimeCount++;\r\n if (mediaTimeCount > media.duration) {\r\n media.emitter.emit('end', media);\r\n }\r\n }, 1000);\r\n\r\n console.debug('Showing Media ' + media.id + ' for ' + media.duration + 's of Region ' + media.region.regionId);\r\n };\r\n\r\n emitter.on('start', function(media: IMedia) {\r\n if (media.mediaType === 'video') {\r\n VideoMedia(media).init();\r\n\r\n if (media.duration > 0) {\r\n startMediaTimer(media);\r\n }\r\n } else if (media.mediaType === 'audio') {\r\n AudioMedia(media).init();\r\n if (media.duration > 0) {\r\n startMediaTimer(media);\r\n }\r\n } else {\r\n startMediaTimer(media);\r\n }\r\n });\r\n\r\n emitter.on('end', function(media) {\r\n if (mediaTimer) {\r\n clearInterval(mediaTimer);\r\n mediaTimeCount = 0;\r\n }\r\n\r\n media.region.playNextMedia();\r\n });\r\n\r\n mediaObject.on = function<E extends keyof IMediaEvents>(event: E, callback: IMediaEvents[E]) {\r\n return emitter.on(event, callback);\r\n };\r\n\r\n mediaObject.emitter = emitter;\r\n\r\n mediaObject.init = function() {\r\n const self = mediaObject;\r\n self.id = props.mediaId;\r\n self.fileId = self.xml?.getAttribute('fileId') || '';\r\n self.idCounter = nextId(props.options);\r\n self.containerName = `M-${self.id}-${self.idCounter}`;\r\n self.iframeName = `${self.containerName}-iframe`;\r\n self.mediaType = self.xml?.getAttribute('type') || '';\r\n self.render = self.xml?.getAttribute('render') || '';\r\n self.duration = parseInt(self.xml?.getAttribute('duration') as string) || 0;\r\n self.options = { ...props.options };\r\n\r\n const $mediaIframe = document.createElement('iframe');\r\n const mediaOptions = self.xml?.getElementsByTagName('options');\r\n\r\n if (mediaOptions) {\r\n for (let _options of Array.from(mediaOptions)) {\r\n // Get options\r\n const _mediaOptions = _options.children;\r\n for (let mediaOption of Array.from(_mediaOptions)) {\r\n self.options[mediaOption.nodeName.toLowerCase()] = mediaOption.textContent;\r\n }\r\n }\r\n }\r\n\r\n // Check for options.uri and add it to media\r\n if (Boolean(self.options['uri'])) {\r\n self.uri = self.options['uri'];\r\n }\r\n\r\n // Show in fullscreen?\r\n if(self.options.showfullscreen === \"1\") {\r\n // Set dimensions as the layout ones\r\n self.divWidth = self.region.layout.sWidth;\r\n self.divHeight = self.region.layout.sHeight;\r\n } else {\r\n // Set dimensions as the region ones\r\n self.divWidth = self.region.sWidth;\r\n self.divHeight = self.region.sHeight;\r\n }\r\n\r\n $mediaIframe.scrolling = 'no';\r\n $mediaIframe.id = self.iframeName;\r\n $mediaIframe.width = `${self.divWidth}px`;\r\n $mediaIframe.height = `${self.divHeight}px`;\r\n $mediaIframe.style.cssText = `border: 0;`;\r\n\r\n const $mediaId = getMediaId(self);\r\n let $media = document.getElementById($mediaId);\r\n\r\n if ($media === null) {\r\n if (self.mediaType === 'video') {\r\n $media = document.createElement('video');\r\n } else if (self.mediaType === 'audio') {\r\n $media = new Audio();\r\n } else {\r\n $media = document.createElement('div');\r\n }\r\n \r\n $media.id = $mediaId;\r\n }\r\n\r\n $media.className = 'media--item';\r\n\r\n /* Scale the Content Container */\r\n $media.style.cssText = `\r\n display: none;\r\n width: ${self.divWidth}px;\r\n height: ${self.divHeight}px;\r\n position: absolute;\r\n background-size: contain;\r\n background-repeat: no-repeat;\r\n background-position: center;\r\n `;\r\n\r\n const $region = document.getElementById(`${self.region.containerName}`);\r\n\r\n const resourceUrlParams: any = {\r\n ...xlr.config.config,\r\n regionOptions: self.region.options,\r\n layoutId: self.region.layout.layoutId,\r\n regionId: self.region.id,\r\n mediaId: self.id,\r\n fileId: self.fileId,\r\n scaleFactor: self.region.layout.scaleFactor,\r\n uri: self.uri,\r\n isGlobalContent: self.mediaType === 'global',\r\n isImageOrVideo: self.mediaType === 'image' || self.mediaType === 'video',\r\n };\r\n\r\n if (self.mediaType === 'image' || self.mediaType === 'video') {\r\n resourceUrlParams.mediaType = self.mediaType;\r\n }\r\n\r\n let tmpUrl = '';\r\n\r\n if (xlr.config.platform === 'CMS') {\r\n tmpUrl = composeResourceUrlByPlatform(xlr.config, resourceUrlParams);\r\n } else if (xlr.config.platform === 'chromeOS') {\r\n tmpUrl = composeResourceUrl(xlr.config, resourceUrlParams);\r\n\r\n if (self.mediaType === 'video') {\r\n tmpUrl = composeVideoUrl(resourceUrlParams);\r\n }\r\n }\r\n\r\n self.url = tmpUrl;\r\n\r\n // Loop if media has loop, or if region has loop and a single media\r\n self.loop =\r\n self.options['loop'] == '1' ||\r\n (self.region.options['loop'] == '1' && self.region.totalMediaObjects == 1);\r\n\r\n if (self.render === 'html' || self.render === 'webpage') {\r\n $mediaIframe.src = self.url;\r\n } else {\r\n $mediaIframe.src = `${self.url}&width=${self.divWidth}&height=${self.divHeight}`;\r\n }\r\n\r\n // Check/set iframe based widgets play status\r\n // Populate mediaIframe content without using src attribute\r\n // let iframeSrc = tmpUrl;\r\n //\r\n // if (self.render !== 'html' && self.render !== 'webpage') {\r\n // iframeSrc = `${tmpUrl}&width=${self.divWidth}&height=${self.divHeight}`;\r\n // }\r\n //\r\n // if (self.render === 'html' || self.render === 'webpage') {\r\n // if (xlr.config.platform === 'CMS') {\r\n // $mediaIframe.src = iframeSrc;\r\n // } else if (xlr.config.platform === 'chromeOS') {\r\n // (async () => {\r\n // const mediaHtml = await fetchText(iframeSrc);\r\n //\r\n // if ($mediaIframe) {\r\n // $mediaIframe.contentDocument?.open();\r\n // $mediaIframe.contentDocument?.write(mediaHtml);\r\n // $mediaIframe.contentDocument?.close();\r\n // }\r\n // })();\r\n // }\r\n // }\r\n\r\n if (self.render === 'html' || self.mediaType === 'ticker' || self.mediaType === 'webpage') {\r\n self.checkIframeStatus = true;\r\n self.iframe = $mediaIframe;\r\n } else if (self.mediaType === \"image\") {\r\n if (self.options['scaletype'] === 'stretch') {\r\n $media.style.cssText = $media.style.cssText.concat(`background-size: 100% 100%;`);\r\n } else if (self.options['scaletype'] === 'fit') {\r\n $media.style.cssText = $media.style.cssText.concat(`background-size: cover;`);\r\n } else {\r\n // Center scale type, do we have align or valign?\r\n const align = (self.options['align'] == \"\") ? \"center\" : self.options['align'];\r\n const valign = (self.options['valign'] == \"\" || self.options['valign'] == \"middle\") ? \"center\" : self.options['valign'];\r\n $media.style.cssText = $media.style.cssText.concat(`background-position: ${align} ${valign}`);\r\n }\r\n } else if (self.mediaType === 'video') {\r\n const $videoMedia = $media as HTMLVideoElement;\r\n\r\n $videoMedia.preload = 'auto';\r\n $videoMedia.textContent = 'Unsupported Video';\r\n\r\n if (Boolean(self.options['mute'])) {\r\n $videoMedia.muted = self.options.mute === '1';\r\n }\r\n\r\n if (Boolean(self.options['scaletype'])) {\r\n if (self.options.scaletype === 'stretch') {\r\n $videoMedia.style.objectFit = 'fill';\r\n }\r\n }\r\n $videoMedia.playsInline = true;\r\n\r\n if (self.loop) {\r\n $videoMedia.loop = true;\r\n }\r\n\r\n $media = $videoMedia;\r\n } else if (self.mediaType === 'audio') {\r\n const $audioMedia = $media as HTMLAudioElement;\r\n\r\n $audioMedia.preload = 'auto';\r\n $audioMedia.textContent = 'Unsupported Audio';\r\n $audioMedia.autoplay = true;\r\n\r\n if (self.loop) {\r\n $audioMedia.loop = true;\r\n }\r\n\r\n $media = $audioMedia;\r\n }\r\n\r\n // Duration is per item condition\r\n if (self.render === 'html' || self.mediaType === 'ticker') {\r\n /* Check if the ticker duration is based on the number of items in the feed */\r\n if (self.options['durationisperitem'] === '1') {\r\n const regex = new RegExp('<!-- NUMITEMS=(.*?) -->');\r\n\r\n (async () => {\r\n let html = await fetchJSON(`${tmpUrl}&width=${self.divWidth}&height=${self.divHeight}`);\r\n console.debug({html});\r\n const res = regex.exec(html);\r\n\r\n if (res !== null) {\r\n self.duration = parseInt(String(self.duration)) * parseInt(res[1]);\r\n }\r\n })();\r\n }\r\n }\r\n\r\n // Check if the media has fade-in/out transitions\r\n if (Boolean(self.options['transin']) && Boolean(self.options['transinduration'])) {\r\n const transInDuration = Number(self.options.transinduration);\r\n const fadeInTrans = transitionElement('fadeIn', { duration: transInDuration });\r\n $media.animate(fadeInTrans.keyframes, fadeInTrans.timing);\r\n }\r\n\r\n // Add media to the region\r\n // Second media if exists, will be off-canvas\r\n // All added media will be hidden by default\r\n // It will start showing when region.nextMedia() function is called\r\n\r\n // When there's only 1 item and loop = false, don't remove the item but leave it at its last state\r\n // For image, and only 1 item, it should still have the transition for next state\r\n // Add conditions for video duration being 0 or 1 and also the loop property\r\n // For video url, we have to create a URL out of the XLF video URL\r\n\r\n /**\r\n * @DONE\r\n * Case 1: Video duration = 0, this will play the video for its entire duration\r\n * Case 2: Video duration is set > 0 and loop = false\r\n * E.g. Set duration = 100s, video duration = 62s\r\n * the video will play until 62s and will stop to its last frame until 100s\r\n * After 100s, it will expire\r\n * Case 3: Video duration is set > 0 and loop = true\r\n * E.g. Set duration = 100s, video duration = 62s, loop = true\r\n * the video will play until 62s and will loop through until the remaining 38s\r\n * to complete the 100s set duration\r\n */\r\n\r\n // Add html node to media for\r\n self.html = $media;\r\n };\r\n\r\n mediaObject.run = function() {\r\n const self = this;\r\n let transInDuration = 1;\r\n let transInDirection: compassPoints = 'E';\r\n\r\n if (Boolean(self.options['transinduration'])) {\r\n transInDuration = Number(self.options.transinduration);\r\n }\r\n\r\n if (Boolean(self.options['transindirection'])) {\r\n transInDirection = self.options.transindirection;\r\n }\r\n\r\n let defaultTransInOptions: TransitionElementOptions = {duration: transInDuration};\r\n let transIn = transitionElement('defaultIn', {duration: defaultTransInOptions.duration});\r\n \r\n if (Boolean(self.options['transin'])) {\r\n let transInName = self.options['transin'];\r\n\r\n if (transInName === 'fly') {\r\n transInName = `${transInName}In`;\r\n defaultTransInOptions.keyframes = flyTransitionKeyframes({\r\n trans: 'in',\r\n direction: transInDirection,\r\n height: self.divHeight,\r\n width: self.divWidth,\r\n });\r\n }\r\n\r\n transIn = transitionElement(transInName, defaultTransInOptions);\r\n }\r\n\r\n const showCurrentMedia = async () => {\r\n let $mediaId = getMediaId(self);\r\n let $media = document.getElementById($mediaId);\r\n const isCMS = xlr.config.platform === 'CMS';\r\n\r\n if (!$media) {\r\n $media = getNewMedia();\r\n }\r\n\r\n if ($media) {\r\n $media.style.setProperty('display', 'block');\r\n\r\n if (Boolean(self.options['transin'])) {\r\n $media.animate(transIn.keyframes, transIn.timing);\r\n }\r\n\r\n if (self.mediaType === 'image' && self.url !== null) {\r\n ($media as HTMLImageElement).style\r\n .setProperty(\r\n 'background-image',\r\n `url(${!isCMS ? self.url : await getDataBlob(self.url)}`\r\n );\r\n } else if (self.mediaType === 'video' && self.url !== null) {\r\n ($media as HTMLVideoElement).src = await preloadMediaBlob(self.url, self.mediaType);\r\n } else if (self.mediaType === 'audio' && self.url !== null) {\r\n ($media as HTMLAudioElement).src =\r\n isCMS ? await preloadMediaBlob(self.url, self.mediaType) : self.url;\r\n } else if ((self.render === 'html' || self.mediaType === 'webpage') &&\r\n self.iframe && self.checkIframeStatus\r\n ) {\r\n // Set state as false ( for now )\r\n self.ready = false;\r\n\r\n // Append iframe\r\n $media.innerHTML = '';\r\n $media.appendChild(self.iframe as Node);\r\n\r\n // On iframe load, set state as ready to play full preview\r\n // (self.iframe) && self.iframe.addEventListener('load', function(){\r\n // self.ready = true;\r\n // if (self.iframe) {\r\n // const iframeStyles = self.iframe.style.cssText;\r\n // self.iframe.style.cssText = iframeStyles?.concat('visibility: visible;');\r\n // }\r\n // });\r\n }\r\n\r\n self.emitter.emit('start', self);\r\n }\r\n };\r\n const getNewMedia = (): HTMLElement | null => {\r\n const $region = document.getElementById(`${self.region.containerName}`);\r\n // This function is for checking whether\r\n // the region still has to show a media item\r\n // when another region is not finished yet\r\n if (self.region.complete && !self.region.layout.allEnded) {\r\n // Add currentMedia to the region\r\n\r\n ($region) && $region.insertBefore(self.html as Node, $region.lastElementChild);\r\n\r\n return self.html as HTMLElement;\r\n }\r\n\r\n return null;\r\n };\r\n\r\n showCurrentMedia();\r\n };\r\n\r\n mediaObject.stop = async function() {\r\n const self = mediaObject;\r\n const $media = document.getElementById(getMediaId(self));\r\n\r\n if ($media) {\r\n $media.style.display = 'none';\r\n $media.remove();\r\n }\r\n };\r\n\r\n mediaObject.init();\r\n\r\n return mediaObject;\r\n}","/*\n * Copyright (C) 2024 Xibo Signage Ltd\n *\n * Xibo - Digital Signage - https://www.xibosignage.com\n *\n * This file is part of Xibo.\n *\n * Xibo is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Lesser General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * any later version.\n *\n * Xibo is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * along with Xibo. If not, see <http://www.gnu.org/licenses/>.\n */\nimport { IMedia } from '../../Types/Media';\nimport { capitalizeStr, getMediaId } from '../Generators';\n\nexport default function VideoMedia(media: IMedia) {\n const videoMediaObject = {\n init() {\n const $videoMedia = document.getElementById(getMediaId(media)) as HTMLVideoElement;\n\n if ($videoMedia) {\n $videoMedia.onloadstart = () => {\n console.debug(`${capitalizeStr(media.mediaType)} for media > ${media.id} has started loading data . . .`);\n };\n $videoMedia.onloadeddata = () => {\n if ($videoMedia.readyState >= 2) {\n console.debug(`${capitalizeStr(media.mediaType)} data for media > ${media.id} has been fully loaded . . .`);\n }\n };\n $videoMedia.oncanplay = () => {\n console.debug(`${capitalizeStr(media.mediaType)} for media > ${media.id} can be played . . .`);\n \n const videoPlayPromise = $videoMedia.play();\n \n if (videoPlayPromise !== undefined) {\n videoPlayPromise.then(() => {\n console.debug('autoplay started . . .');\n // Autoplay restarted\n }).catch(error => {\n $videoMedia.muted = true;\n $videoMedia.play();\n });\n }\n };\n $videoMedia.onplaying = () => {\n console.debug(`${capitalizeStr(media.mediaType)} for media > ${media.id} is now playing . . .`);\n };\n\n if (media.duration === 0) {\n $videoMedia.ondurationchange = () => {\n console.debug('Showing Media ' + media.id + ' for ' + $videoMedia.duration + 's of Region ' + media.region.regionId);\n };\n $videoMedia.onended = () => {\n console.debug(`${capitalizeStr(media.mediaType)} for media > ${media.id} has ended playing . . .`);\n media.emitter?.emit('end', media);\n };\n }\n }\n }\n }\n\n return videoMediaObject;\n}\n","/*\n * Copyright (C) 2024 Xibo Signage Ltd\n *\n * Xibo - Digital Signage - https://www.xibosignage.com\n *\n * This file is part of Xibo.\n *\n * Xibo is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Lesser General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * any later version.\n *\n * Xibo is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * along with Xibo. If not, see <http://www.gnu.org/licenses/>.\n */\nimport { IMedia } from '../../Types/Media';\nimport { capitalizeStr, getMediaId } from '../Generators';\n\nimport './media.css';\n\nexport default function AudioMedia(media: IMedia) {\n const audioMediaObject = {\n init() {\n const $audioMedia = document.getElementById(getMediaId(media)) as HTMLAudioElement;\n let $playBtn: HTMLButtonElement | null = null;\n\n if ($audioMedia) {\n $audioMedia.onloadstart = () => {\n console.debug(`${capitalizeStr(media.mediaType)} for media > ${media.id} has started loading data . . .`);\n };\n $audioMedia.onloadeddata = () => {\n if ($audioMedia.readyState >= 2) {\n console.debug(`${capitalizeStr(media.mediaType)} data for media > ${media.id} has been fully loaded . . .`);\n }\n };\n $audioMedia.oncanplay = () => {\n console.debug(`${capitalizeStr(media.mediaType)} for media > ${media.id} can be played . . .`);\n };\n $audioMedia.onplaying = () => {\n console.debug(`${capitalizeStr(media.mediaType)} for media > ${media.id} is now playing . . .`);\n\n if ($playBtn !== null) {\n $playBtn.remove();\n }\n };\n\n const audioPlayPromise = $audioMedia.play();\n \n if (audioPlayPromise !== undefined) {\n audioPlayPromise.then(() => {\n console.debug('autoplay started . . .');\n // Autoplay restarted\n }).catch(error => {\n if (error.name === 'NotAllowedError') {\n // Let's show a play audio button\n $playBtn = document.createElement('button');\n\n $playBtn.classList.add('play-audio-btn');\n $playBtn.textContent = 'Play Audio';\n $playBtn.addEventListener('click', () => {\n $audioMedia.muted = false;\n $audioMedia.play();\n });\n $audioMedia.parentNode?.insertBefore($playBtn, $audioMedia.nextSibling);\n }\n });\n }\n if (media.duration === 0) {\n $audioMedia.ondurationchange = () => {\n console.debug('Showing Media ' + media.id + ' for ' + $audioMedia.duration + 's of Region ' + media.region.regionId);\n };\n $audioMedia.onended = () => {\n console.debug(`${capitalizeStr(media.mediaType)} for media > ${media.id} has ended playing . . .`);\n media.emitter?.emit('end', media);\n };\n }\n }\n },\n };\n\n return audioMediaObject;\n}\n","/*\n * Copyright (C) 2024 Xibo Signage Ltd\n *\n * Xibo - Digital Signage - https://www.xibosignage.com\n *\n * This file is part of Xibo.\n *\n * Xibo is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Lesser General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * any later version.\n *\n * Xibo is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public License\n * along with Xibo. If not, see <http://www.gnu.org/licenses/>.\n */\n// import Moveable from 'moveable';\nimport { ILayout, IMedia, IRegion, OptionsType } from '../../types';\nimport { getAllAttributes, nextId } from '../Generators/Generators';\nimport './action-controller.css';\n\nexport class Action {\n readonly id: string;\n readonly xml: Element;\n\n constructor(id: string, xml: Element) {\n this.id = id;\n this.xml = xml;\n }\n}\n\nexport class ActionsWrapper extends HTMLDivElement {\n constructor() {\n super();\n\n this.classList.add('action-controller', 'noselect');\n }\n}\n\ncustomElements.define('action-controller', ActionsWrapper, { extends: 'div' });\n\nexport type InactOptions = {\n [k: string]: any;\n} & OptionsType['previewTranslations'];\n\nexport default class ActionController {\n readonly parent: ILayout;\n readonly actions: Action[];\n readonly options: InactOptions;\n readonly $actionController: ActionsWrapper;\n readonly $actionListContainer: Element | null;\n translations: any = {};\n\n constructor(parent: ILayout, actions: Action[], options: InactOptions) {\n this.parent = parent;\n this.actions = actions;\n this.options = options;\n this.$actionController = document.createElement('div', { is: 'action-controller' });\n this.$actionListContainer = null;\n\n this.init();\n }\n\n init() {\n const self = this;\n let previewTranslations: any = {};\n\n // get preview translations\n if ('previewTranslations' in window) {\n previewTranslations = window['previewTranslations'];\n self.translations = previewTranslations;\n }\n \n const $container = document.getElementById(this.parent.containerName);\n const $actionTitle = document.createElement('div');\n const $actionsContainer = document.createElement('div');\n\n $actionTitle.classList.add('action-controller-title');\n $actionTitle.innerHTML = `\n <button class=\"toggle\"></button>\n <span class=\"title\">${previewTranslations.actionControllerTitle}</span>\n `;\n\n $actionsContainer.classList.add('actions-container');\n\n if ($container) {\n $container.insertBefore(this.$actionController, $container.firstElementChild);\n \n this.$actionController.appendChild($actionTitle);\n this.$actionController.appendChild($actionsContainer);\n\n // Loop through actions\n Array.from(this.actions).forEach(function(newAction) {\n // Create new action object\n const $newAction = document.createElement('div');\n\n // Copy element attributes\n const attributes = getAllAttributes(newAction.xml);\n\n Array.from(Object.keys(attributes)).forEach((attribKey) => {\n $newAction.setAttribute(`data-${attribKey}`, attributes[attribKey].value);\n $newAction.setAttribute(attribKey, attributes[attribKey].value);\n });\n\n // Build html for the new action\n let html = '';\n\n // Add action type\n html += '<span class=\"action-row-title\">' + previewTranslations[$newAction.getAttribute('actiontype') || ''];\n\n if ($newAction.getAttribute('actiontype') == 'navWidget') {\n html += ' <span title=\"' + previewTranslations.widgetId + '\">[' + $newAction.getAttribute('widgetid') + ']</span>';\n } else if ($newAction.getAttribute('actiontype') == 'navLayout') {\n html += ' <span title=\"' + previewTranslations.layoutCode + '\">[' + $newAction.getAttribute('layoutcode') + ']</span>';\n }\n html += '</span>';\n\n // Add target\n html += '<span class=\"action-row-target\" title=\"' + previewTranslations.target + '\">' + $newAction.getAttribute('target');\n if ($newAction.getAttribute('targetid') != '') {\n html += '(' + $newAction.getAttribute('targetid') + $newAction.getAttribute('layoutcode') + ')';\n }\n html += '</span>';\n \n // Add HTML string to the action\n $newAction.innerHTML = html;\n\n // Append new action to the controller\n $newAction.classList.add('action');\n $newAction.setAttribute('originalid', newAction.id);\n $newAction.setAttribute('id', 'A-' + newAction.id + '-' + nextId(self.options as OptionsType));\n $actionsContainer.insertBefore($newAction, $actionsContainer.lastElementChild);\n });\n\n // \n // Enable dragging\n // const $draggableContainer = new Moveable($container, {\n // target: this.$actionController,\n // draggable: true,\n // });\n\n // Toggle actions visibility\n const $actionsToggler = this.$actionController.querySelector<HTMLElement>('.toggle');\n \n if ($actionsToggler) {\n $actionsToggler.onclick = function() {\n self.$actionController.classList.toggle('d-none');\n };\n }\n\n const $webhookActions = this.$actionController.querySelectorAll<HTMLElement>('.action[triggertype=\"webhook\"]');\n // Display according to the number of clickable actions\n this.$actionController.style.setProperty(\n 'display',\n $webhookActions.length === 0 ?\n 'none' : 'flex'\n );\n\n // Handle webhook action trigger click\n if ($webhookActions.length > 0) {\n $webhookActions.forEach(($webhookAction) => {\n $webhookAction.onclick = function(event: Event) {\n event.stopPropagation();\n self.runAction($webhookAction.dataset, self.options);\n };\n $webhookAction.classList.add('clickable');\n });\n }\n }\n }\n\n openLayoutInNewTab(layoutCode: string, options: InactOptions) {\n if(confirm(this.translations.navigateToLayout.replace('[layoutTag]', layoutCode))) {\n var url = options.layoutPreviewUrl.replace('[layoutCode]', layoutCode) + '?findByCode=1';\n window.open(url, '_blank');\n }\n }\n\n /** Change media in region (next/previous) */\n nextMediaInRegion(regionId: string, actionType: string) {\n // Find target region\n this.parent.regions.forEach((regionObj) => {\n if (regionObj.id === regionId) {\n if (actionType === 'next') {\n regionObj.playNextMedia();\n } else {\n regionObj.playPreviousMedia();\n }\n }\n });\n }\n\n loadMediaInRegion(regionId: string, widgetId: string) {\n const self = this;\n // Find target region\n let targetRegion: IRegion | undefined;\n \n self.parent.regions.forEach((regionObj) => {\n if (regionObj.id === regionId) {\n targetRegion = regionObj;\n }\n });\n\n // Find media in actions\n let targetMedia: IMedia | undefined;\n if (targetRegion) {\n targetRegion.mediaObjectsActions.forEach((media) => {\n if (media.id === widgetId) {\n targetMedia = media;\n }\n });\n }\n\n // Mark media as temporary (removed after region stop playing or loops)\n if (targetMedia) {\n targetMedia.singlePlay = true;\n }\n\n // If region is empty, remove the background color and empty message\n if (targetRegion?.mediaObjects.length === 0) {\n targetRegion.complete = false;\n }\n\n // Create media in region and play it next\n targetRegion?.mediaObjects.splice(targetRegion.currentMediaIndex + 1, 0, targetMedia as IMedia);\n targetRegion?.playNextMedia();\n }\n\n /** Run action based on action data */\n runAction(actionData: {[k: string]: any}, options: InactOptions) {\n if(actionData.actiontype == 'navLayout') {\n // Open layout preview in a new tab\n this.openLayoutInNewTab(actionData.layoutcode, options);\n } else if((actionData.actiontype == 'previous' || actionData.actiontype == 'next') && actionData.target == 'region') {\n this.nextMediaInRegion(actionData.targetid, actionData.actiontype);\n } else if(actionData.actiontype == 'navWidget' && actionData.target == 'region') {\n this.loadMediaInRegion(actionData.targetid, actionData.widgetid);\n } else {\n // TODO Handle other action types ( later? )\n console.log(actionData.actiontype + ' > ' + actionData.target + '[' + actionData.targetid + ']');\n }\n };\n\n initTouchActions() {\n const self = this;\n\n this.$actionController.querySelectorAll<HTMLElement>('.action[triggerType=\"touch\"]').forEach(function($el) {\n const dataset = $el.dataset;\n\n // Find source object\n let $sourceObj;\n\n if (dataset.source === 'layout') {\n $sourceObj = document.getElementById(self.parent.containerName);\n } else {\n const regionObjects = Array.from(self.parent.regions);\n\n // Loop through layout regions\n for (const regionObj of regionObjects) {\n if (dataset.source === 'region') {\n // Try to find the region\n if (regionObj.id === dataset.sourceid) {\n $sourceObj = document.getElementById(regionObj.containerName);\n break;\n }\n } else if (dataset.source === 'widget') {\n // Try to find widget/media\n const mediaObjects = Array.from(regionObj.mediaObjects);\n\n for (const mediaObject of mediaObjects) {\n if (mediaObject.id === dataset.sourceid) {\n $sourceObj = document.getElementById(mediaObject.containerName);\n break;\n }\n }\n }\n\n // Break loop if we already have a $sourceObj\n if ($sourceObj != undefined) {\n break;\n }\n }\n }\n\n // Handle source click\n // FIXME: We need to handle the case where a drawer widget has an action and it has been loaded to the preview\n if($sourceObj != undefined) {\n $sourceObj.onclick = function(ev: Event) {\n ev.stopPropagation();\n self.runAction(dataset, self.options);\n };\n $sourceObj.classList.add('clickable');\n }\n });\n }\n}\n","/*\r\n * Copyright (C) 2024 Xibo Signage Ltd\r\n *\r\n * Xibo - Digital Signage - https://www.xibosignage.com\r\n *\r\n * This file is part of Xibo.\r\n *\r\n * Xibo is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Lesser General Public License as published by\r\n * the Free Software Foundation, either version 3 of the License, or\r\n * any later version.\r\n *\r\n * Xibo is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Lesser General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Lesser General Public License\r\n * along with Xibo. If not, see <http://www.gnu.org/licenses/>.\r\n */\r\nimport {ILayout, InputLayoutType, OptionsType} from '../Layout';\r\nimport {platform} from '../../Modules/Platform';\r\n\r\nexport type PrepareLayoutsType = {\r\n moveNext?: boolean;\r\n};\r\n\r\nexport enum ELayoutType {\r\n CURRENT,\r\n NEXT,\r\n}\r\n\r\nexport interface IXlr {\r\n inputLayouts: InputLayoutType[],\r\n config: OptionsType,\r\n layouts: ILayout[],\r\n currentLayoutIndex: number;\r\n currentLayoutId: number | null;\r\n currentLayout: ILayout | undefined;\r\n nextLayout: ILayout | undefined;\r\n bootstrap(): void;\r\n init(): Promise<IXlr>;\r\n playSchedules(xlr: IXlr): void;\r\n prepareLayoutXlf(inputLayout: ILayout | undefined): Promise<ILayout>;\r\n prepareLayouts(): Promise<IXlr>;\r\n updateLayouts(inputLayouts: InputLayoutType[]): void;\r\n updateLoop(inputLayouts: InputLayoutType[]): void;\r\n}\r\n\r\nexport const initialXlr: IXlr = {\r\n inputLayouts: [],\r\n config: platform,\r\n layouts: [],\r\n currentLayoutIndex: 0,\r\n currentLayoutId: null,\r\n currentLayout: undefined,\r\n nextLayout: undefined,\r\n bootstrap() {\r\n },\r\n init() {\r\n return Promise.resolve(<IXlr>{});\r\n },\r\n playSchedules() {\r\n },\r\n prepareLayoutXlf(inputLayout: ILayout | undefined): Promise<ILayout> {\r\n return Promise.resolve(<ILayout>{});\r\n },\r\n prepareLayouts(): Promise<IXlr> {\r\n return Promise.resolve(<IXlr>{});\r\n },\r\n updateLayouts(inputLayouts: InputLayoutType[]) {\r\n },\r\n updateLoop(inputLayouts: InputLayoutType[]) {\r\n }\r\n};\r\n","/*\r\n * Copyright (C) 2024 Xibo Signage Ltd\r\n *\r\n * Xibo - Digital Signage - https://www.xibosignage.com\r\n *\r\n * This file is part of Xibo.\r\n *\r\n * Xibo is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Lesser General Public License as published by\r\n * the Free Software Foundation, either version 3 of the License, or\r\n * any later version.\r\n *\r\n * Xibo is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Lesser General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Lesser General Public License\r\n * along with Xibo. If not, see <http://www.gnu.org/licenses/>.\r\n */\r\nimport {createNanoEvents} from 'nanoevents';\r\nimport {\r\n GetLayoutParamType,\r\n GetLayoutType,\r\n ILayout,\r\n initialLayout,\r\n OptionsType,\r\n} from '../../Types/Layout';\r\nimport { IXlr } from '../../Types/XLR';\r\nimport { nextId } from '../Generators';\r\nimport { Region } from '../Region';\r\n\r\nimport './layout.css';\r\nimport {composeBgUrlByPlatform, getIndexByLayoutId} from '../Generators/Generators';\r\nimport ActionController, { Action } from '../ActionController';\r\n\r\nconst playAgainClickHandle = function(ev: { preventDefault: () => void; }) {\r\n ev.preventDefault();\r\n history.go(0);\r\n};\r\n\r\nexport function initRenderingDOM(targetContainer: Element | null) {\r\n let _targetContainer = targetContainer;\r\n const previewPlayer = document.createElement('div');\r\n const previewScreen = document.createElement('div');\r\n const endPlay = document.createElement('div');\r\n const playAgainLink = document.createElement('a');\r\n\r\n // Preview player\r\n previewPlayer.className = 'player-preview';\r\n previewPlayer.id = 'player_container';\r\n\r\n // Preview screen\r\n previewScreen.className = 'screen-preview';\r\n previewScreen.id = 'screen_container';\r\n\r\n // Ended play\r\n endPlay.className = 'preview-ended';\r\n endPlay.id = 'play_ended';\r\n endPlay.style.display = 'none';\r\n\r\n // Play again link\r\n playAgainLink.id = 'play_back_preview';\r\n playAgainLink.className = 'play-back-preview';\r\n playAgainLink.style.cssText = 'text-decoration: none; color: #ffffff;';\r\n playAgainLink.innerHTML = 'Play again?';\r\n playAgainLink.removeEventListener('click', playAgainClickHandle);\r\n playAgainLink.addEventListener('click', playAgainClickHandle);\r\n\r\n if (!_targetContainer) {\r\n _targetContainer = document.body;\r\n }\r\n\r\n if (_targetContainer) {\r\n if (_targetContainer.querySelector('#player_container') === null) {\r\n _targetContainer.insertBefore(previewPlayer, _targetContainer.firstChild);\r\n\r\n if (previewPlayer.querySelector('#screen_container') === null) {\r\n previewPlayer.appendChild(previewScreen);\r\n }\r\n\r\n if (previewPlayer.querySelector('#play_ended') === null) {\r\n previewPlayer.appendChild(endPlay);\r\n\r\n if (endPlay.querySelector('a') === null) {\r\n endPlay.appendChild(playAgainLink);\r\n }\r\n }\r\n }\r\n }\r\n}\r\n\r\nexport async function getXlf(layoutOptions: OptionsType) {\r\n let apiHost = window.location.origin;\r\n\r\n let xlfUrl = apiHost + layoutOptions.xlfUrl;\r\n let fetchOptions: RequestInit = {};\r\n\r\n if (layoutOptions.platform === 'CMS') {\r\n xlfUrl = apiHost + layoutOptions.xlfUrl;\r\n fetchOptions.mode = 'no-cors';\r\n } else if (layoutOptions.platform === 'chromeOS') {\r\n xlfUrl = layoutOptions.xlfUrl;\r\n fetchOptions.mode = 'cors';\r\n fetchOptions.headers = {\r\n 'Content-Type': 'text/xml',\r\n };\r\n } else if (layoutOptions.platform !== 'CMS' && layoutOptions.appHost !== null) {\r\n xlfUrl = layoutOptions.appHost + layoutOptions.xlfUrl;\r\n }\r\n\r\n const res = await fetch(xlfUrl);\r\n\r\n return await res.text();\r\n}\r\n\r\nexport function handleAxiosError(error: any, message?: string) {\r\n console.error(error);\r\n if (error.response.status == 500) {\r\n // SOAP responses are always 500's\r\n // Return the body\r\n throw new Error(error.response.data);\r\n } else {\r\n throw new Error(message || 'Unknown Error');\r\n }\r\n}\r\n\r\nexport function getLayout(params: GetLayoutParamType): GetLayoutType {\r\n let _currentLayout = undefined;\r\n let _nextLayout = undefined;\r\n let {\r\n inputLayouts,\r\n currentLayout,\r\n nextLayout,\r\n currentLayoutIndex: currLayoutIndx\r\n } = params.xlr;\r\n const hasLayout = inputLayouts.length > 0;\r\n let currentLayoutIndex = currLayoutIndx;\r\n let nextLayoutIndex = currentLayoutIndex + 1;\r\n\r\n if (currentLayout === undefined && nextLayout === undefined) {\r\n let activeLayout;\r\n // Preview just got started\r\n if (hasLayout) {\r\n let nextLayoutTemp = {...initialLayout};\r\n activeLayout = inputLayouts[currentLayoutIndex];\r\n _currentLayout = {...initialLayout, ...activeLayout};\r\n\r\n if (inputLayouts.length > 1) {\r\n nextLayoutTemp = {...nextLayoutTemp, ...inputLayouts[nextLayoutIndex]};\r\n _nextLayout = nextLayoutTemp;\r\n } else {\r\n _nextLayout = _currentLayout;\r\n }\r\n\r\n _currentLayout.id = activeLayout.layoutId;\r\n\r\n if (nextLayoutTemp) {\r\n _nextLayout.id = nextLayoutTemp.layoutId;\r\n }\r\n }\r\n } else {\r\n if (hasLayout) {\r\n _currentLayout = nextLayout;\r\n\r\n currentLayoutIndex = getIndexByLayoutId(inputLayouts, _currentLayout?.layoutId).index as number;\r\n nextLayoutIndex = currentLayoutIndex + 1;\r\n\r\n if (inputLayouts.length > 1 && nextLayoutIndex < inputLayouts.length) {\r\n if (Boolean(params.xlr.layouts[nextLayoutIndex])) {\r\n _nextLayout = params.xlr.layouts[nextLayoutIndex];\r\n } else {\r\n _nextLayout = {...initialLayout, ...inputLayouts[nextLayoutIndex]};\r\n }\r\n }\r\n\r\n // If _nextLayout is undefined, then we go back to first layout\r\n if (_nextLayout === undefined) {\r\n _nextLayout = params.xlr.layouts[0];\r\n }\r\n }\r\n }\r\n\r\n return {\r\n currentLayoutIndex,\r\n inputLayouts: params.xlr.inputLayouts,\r\n current: _currentLayout,\r\n next: _nextLayout,\r\n }\r\n}\r\n\r\nexport interface ILayoutEvents {\r\n start: (layout: ILayout) => void;\r\n end: (layout: ILayout) => void;\r\n}\r\n\r\nexport default function Layout(\r\n data: Document | null,\r\n options: OptionsType,\r\n xlr: IXlr,\r\n layout?: ILayout\r\n) {\r\n const props = {\r\n data: data,\r\n options: options,\r\n layout: layout || initialLayout,\r\n }\r\n const emitter = createNanoEvents<ILayoutEvents>();\r\n\r\n emitter.on('start', (layout: ILayout) => {\r\n layout.done = false;\r\n console.debug('Layout start emitted > Layout ID > ', layout.id);\r\n });\r\n\r\n emitter.on('end', async (layout: ILayout) => {\r\n console.debug('Ending layout with ID of > ', layout.layoutId);\r\n /* Remove layout that has ended */\r\n const $layout = document.getElementById(layout.containerName);\r\n\r\n layout.done = true;\r\n console.debug({$layout});\r\n\r\n if ($layout !== null) {\r\n $layout.remove();\r\n }\r\n\r\n if (xlr.config.platform !== 'CMS') {\r\n // Transition next layout to current layout and prepare next layout if exist\r\n xlr.prepareLayouts().then((parent) => {\r\n xlr.playSchedules(parent);\r\n });\r\n }\r\n });\r\n\r\n const layoutObject: ILayout = {\r\n ...props.layout,\r\n options: props.options,\r\n };\r\n\r\n layoutObject.on = function<E extends keyof ILayoutEvents>(event: E, callback: ILayoutEvents[E]) {\r\n return emitter.on(event, callback);\r\n };\r\n layoutObject.emitter = emitter;\r\n\r\n layoutObject.run = function() {\r\n const layout = layoutObject;\r\n const $layoutContainer = document.getElementById(`${layout.containerName}`);\r\n const $splashScreen = document.getElementById(`splash_${layout.id}`);\r\n\r\n if ($layoutContainer) {\r\n $layoutContainer.style.display = 'block';\r\n }\r\n\r\n if ($splashScreen) {\r\n $splashScreen.style.display = 'none';\r\n }\r\n\r\n console.debug('Layout running > Layout ID > ', layout.id);\r\n console.debug('Layout Regions > ', layout.regions);\r\n for (let i = 0; i < layout.regions.length; i++) {\r\n // playLog(4, \"debug\", \"Running region \" + self.regions[i].id, false);\r\n layout.regions[i].run();\r\n }\r\n };\r\n\r\n layoutObject.prepareLayout = function(){\r\n layoutObject.parseXlf();\r\n };\r\n\r\n layoutObject.parseXlf = function() {\r\n const layout = this;\r\n const {options} = layout;\r\n\r\n layout.done = false;\r\n layout.allEnded = false;\r\n layout.allExpired = false;\r\n layout.containerName = \"L\" + layout.id + \"-\" + nextId(options);\r\n layout.regions = [];\r\n\r\n /* Create a hidden div to show the layout in */\r\n let $layout = document.getElementById(layout.containerName);\r\n\r\n if ($layout === null) {\r\n $layout = document.createElement('div');\r\n $layout.id = layout.containerName;\r\n }\r\n\r\n let $screen = document.getElementById('screen_container');\r\n ($screen) && $screen.appendChild($layout);\r\n\r\n if ($layout) {\r\n $layout.style.display = 'none';\r\n if (xlr.config.platform === 'CMS') {\r\n $layout.style.outline = 'red solid thin';\r\n }\r\n }\r\n\r\n layout.layoutNode = props.data;\r\n\r\n /* Calculate the screen size */\r\n layout.sw = $screen?.offsetWidth || 0;\r\n layout.sh = $screen?.offsetHeight || 0;\r\n\r\n layout.xw = Number(layout.layoutNode?.firstElementChild?.getAttribute('width'));\r\n layout.xh = Number(layout.layoutNode?.firstElementChild?.getAttribute('height'));\r\n layout.zIndex = Number(layout.layoutNode?.firstElementChild?.getAttribute('zindex')) || 0;\r\n\r\n /* Calculate Scale Factor */\r\n layout.scaleFactor = Math.min((layout.sw / layout.xw), (layout.sh / layout.xh));\r\n layout.sWidth = layout.xw * layout.scaleFactor;\r\n layout.sHeight = layout.xh * layout.scaleFactor;\r\n layout.offsetX = Math.abs(layout.sw - layout.sWidth) / 2;\r\n layout.offsetY = Math.abs(layout.sh - layout.sHeight) / 2;\r\n\r\n /* Scale the Layout Container */\r\n if ($layout) {\r\n $layout.style.width = `${layout.sWidth}px`;\r\n $layout.style.height = `${layout.sHeight}px`;\r\n $layout.style.position = 'absolute';\r\n $layout.style.left = `${layout.offsetX}px`;\r\n $layout.style.top = `${layout.offsetY}px`;\r\n }\r\n\r\n if ($layout && layout.zIndex !== null) {\r\n $layout.style.zIndex = `${layout.zIndex}`;\r\n }\r\n\r\n /* Set the layout background */\r\n layout.bgColor = layout.layoutNode?.firstElementChild?.getAttribute('bgcolor') || '';\r\n layout.bgImage = layout.layoutNode?.firstElementChild?.getAttribute('background') || '';\r\n\r\n if (!(layout.bgImage === \"\" || typeof layout.bgImage === 'undefined')) {\r\n /* Extract the image ID from the filename */\r\n layout.bgId = layout.bgImage.substring(0, layout.bgImage.indexOf('.'));\r\n\r\n const bgImageUrl = composeBgUrlByPlatform(\r\n xlr.config.platform,\r\n {\r\n ...options,\r\n layout,\r\n }\r\n );\r\n\r\n if ($layout) {\r\n $layout.style.backgroundImage = `url(\"${bgImageUrl}\")`;\r\n $layout.style.backgroundRepeat = 'no-repeat';\r\n $layout.style.backgroundSize = `${layout.sWidth}px ${layout.sHeight}px`;\r\n $layout.style.backgroundPosition = '0px 0px';\r\n }\r\n }\r\n\r\n // Set the background color\r\n if ($layout && layout.bgColor) {\r\n $layout.style.backgroundColor = `${layout.bgColor}`;\r\n }\r\n\r\n // Hide if layout is not the currentLayout\r\n if ($layout && xlr.currentLayoutId !== undefined && xlr.currentLayoutId !== layout.id) {\r\n $layout.style.display = 'none';\r\n }\r\n\r\n // Create actions\r\n const layoutActions = Array.from(layout?.layoutNode?.getElementsByTagName('action') || []);\r\n Array.from(layoutActions).forEach((actionXml, indx) => {\r\n layout.actions.push(new Action(actionXml?.getAttribute('id') || '', actionXml));\r\n });\r\n\r\n // Create interactive actions\r\n layout.actionController = new ActionController(\r\n layout,\r\n layout.actions,\r\n options,\r\n );\r\n\r\n // Create drawer\r\n const layoutDrawers = Array.from(layout?.layoutNode?.getElementsByTagName('drawer') || []);\r\n\r\n Array.from(layoutDrawers).forEach((layoutDrawerXml) => {\r\n layout.drawer = layoutDrawerXml;\r\n });\r\n\r\n // Create regions\r\n const layoutRegions = Array.from(layout?.layoutNode?.getElementsByTagName('region') || []);\r\n\r\n Array.from(layoutRegions).forEach((regionXml, indx) => {\r\n const regionObj = Region(\r\n layout,\r\n regionXml,\r\n regionXml?.getAttribute('id') || '',\r\n options,\r\n xlr,\r\n );\r\n\r\n regionObj.index = indx;\r\n layout.regions.push(regionObj);\r\n });\r\n\r\n layout.actionController.initTouchActions();\r\n };\r\n\r\n layoutObject.regionExpired = function() {\r\n const self = layoutObject;\r\n self.allExpired = true;\r\n\r\n for (let layoutRegion of self.regions) {\r\n if (!layoutRegion.complete) {\r\n self.allExpired = false;\r\n }\r\n }\r\n\r\n if (self.allExpired) {\r\n self.end();\r\n }\r\n };\r\n\r\n layoutObject.regionEnded = function() {\r\n const self = layoutObject;\r\n self.allEnded = true;\r\n \r\n for (var i = 0; i < self.regions.length; i++) {\r\n if (! self.regions[i].ended) {\r\n self.allEnded = false;\r\n }\r\n }\r\n \r\n if (self.allEnded) {\r\n self.stopAllMedia().then(async () => {\r\n console.debug('starting to end layout . . .');\r\n if (xlr.config.platform === 'CMS') {\r\n const $end = document.getElementById('play_ended');\r\n const $preview = document.getElementById('screen_container');\r\n \r\n if ($preview) {\r\n while($preview.firstChild) {\r\n $preview.removeChild($preview.firstChild);\r\n }\r\n \r\n $preview.style.display = 'none';\r\n }\r\n \r\n if ($end) {\r\n $end.style.display = 'block';\r\n }\r\n }\r\n \r\n self.emitter.emit('end', self);\r\n });\r\n\r\n }\r\n };\r\n\r\n layoutObject.end = function() {\r\n console.debug('Executing Layout::end and Calling Region::end ', layoutObject);\r\n\r\n /* Ask the layout to gracefully stop running now */\r\n for (let layoutRegion of layoutObject.regions) {\r\n layoutRegion.end();\r\n }\r\n };\r\n\r\n layoutObject.stopAllMedia = function() {\r\n console.debug('Stopping all media . . .');\r\n return new Promise(async (resolve) => {\r\n for(var i = 0;i < layoutObject.regions.length;i++) {\r\n var region = layoutObject.regions[i];\r\n for(var j = 0;j < region.mediaObjects.length;j++) {\r\n var media = region.mediaObjects[j];\r\n await media.stop();\r\n }\r\n }\r\n\r\n resolve();\r\n });\r\n };\r\n\r\n layoutObject.prepareLayout();\r\n\r\n return layoutObject;\r\n}\r\n","/*\r\n * Copyright (C) 2024 Xibo Signage Ltd\r\n *\r\n * Xibo - Digital Signage - https://www.xibosignage.com\r\n *\r\n * This file is part of Xibo.\r\n *\r\n * Xibo is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Lesser General Public License as published by\r\n * the Free Software Foundation, either version 3 of the License, or\r\n * any later version.\r\n *\r\n * Xibo is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Lesser General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Lesser General Public License\r\n * along with Xibo. If not, see <http://www.gnu.org/licenses/>.\r\n */\r\nimport { createNanoEvents } from 'nanoevents';\r\nimport { ILayout, OptionsType } from '../../Types/Layout';\r\nimport { initialRegion, IRegion, IRegionEvents } from '../../Types/Region';\r\nimport { IMedia } from '../../Types/Media';\r\nimport { getMediaId, nextId } from '../Generators';\r\nimport { platform } from '../Platform';\r\nimport { Media } from '../Media';\r\nimport {\r\n TransitionElementOptions,\r\n TransitionNameType,\r\n compassPoints,\r\n flyTransitionKeyframes,\r\n transitionElement,\r\n} from '../Transitions';\r\nimport {IXlr} from '../../Types/XLR';\r\nimport { getAllAttributes } from '../Generators/Generators';\r\n\r\nexport default function Region(\r\n layout: ILayout,\r\n xml: Element,\r\n regionId: string,\r\n options: OptionsType,\r\n xlr: IXlr,\r\n) {\r\n const props = {\r\n layout: layout,\r\n xml: xml,\r\n regionId: regionId,\r\n options: options,\r\n }\r\n const emitter = createNanoEvents<IRegionEvents>();\r\n let regionObject: IRegion = {\r\n ...initialRegion,\r\n ...props,\r\n };\r\n\r\n regionObject.prepareRegion = function() {\r\n const self = regionObject;\r\n const {layout, options} = self;\r\n self.complete = false;\r\n self.ending = false;\r\n self.ended = false;\r\n self.id = props.regionId;\r\n self.uniqueId = `${nextId(self.options as OptionsType & IRegion[\"options\"])}`;\r\n self.options = {...platform, ...props.options};\r\n self.containerName = `R-${self.id}-${self.uniqueId}`;\r\n self.xml = props.xml;\r\n self.mediaObjects = [];\r\n\r\n self.sWidth = (self.xml) && Number(self.xml?.getAttribute('width')) * layout.scaleFactor;\r\n self.sHeight = (self.xml) && Number(self.xml?.getAttribute('height')) * layout.scaleFactor;\r\n self.offsetX = (self.xml) && Number(self.xml?.getAttribute('left')) * layout.scaleFactor;\r\n self.offsetY = (self.xml) && Number(self.xml?.getAttribute('top')) * layout.scaleFactor;\r\n self.zIndex = (self.xml) && Number(self.xml?.getAttribute('zindex'));\r\n \r\n const regionOptions = self.xml?.getElementsByTagName('options');\r\n\r\n if (regionOptions) {\r\n for (let _options of Array.from(regionOptions)) {\r\n // Get options\r\n const _regionOptions = _options.children;\r\n for (let regionOption of Array.from(_regionOptions)) {\r\n self.options[regionOption.nodeName.toLowerCase()] = regionOption.textContent;\r\n }\r\n }\r\n }\r\n\r\n\r\n let $region = document.getElementById(self.containerName);\r\n const $layout = document.getElementById(`${self.layout.containerName}`);\r\n\r\n if ($region === null) {\r\n $region = document.createElement('div');\r\n $region.id = self.containerName;\r\n }\r\n\r\n ($layout) && $layout.appendChild($region);\r\n\r\n /* Scale the Layout Container */\r\n /* Add region styles */\r\n $region.style.cssText = `\r\n width: ${self.sWidth}px;\r\n height: ${self.sHeight}px;\r\n position: absolute;\r\n left: ${self.offsetX}px;\r\n top: ${self.offsetY}px;\r\n z-index: ${Math.round(self.zIndex)};\r\n `;\r\n $region.className = 'region--item';\r\n\r\n /* Parse region media objects */\r\n const regionMediaItems = Array.from(self.xml.getElementsByTagName('media'));\r\n self.totalMediaObjects = regionMediaItems.length;\r\n\r\n Array.from(regionMediaItems).forEach((mediaXml, indx) => {\r\n const mediaObj = Media(\r\n self,\r\n mediaXml?.getAttribute('id') || '',\r\n mediaXml,\r\n options as OptionsType & IRegion[\"options\"],\r\n xlr,\r\n );\r\n\r\n mediaObj.index = indx;\r\n self.mediaObjects.push(mediaObj);\r\n });\r\n\r\n\r\n // Add media to region for targetted actions\r\n self.layout.actionController?.actions.forEach((action) => {\r\n const attributes = getAllAttributes(action.xml);\r\n\r\n if (attributes.target.value === 'region' &&\r\n attributes.actionType.value === 'navWidget' &&\r\n attributes.targetId.value == self.id\r\n ) {\r\n const drawerMediaItems = Array.from(self.layout.drawer?.getElementsByTagName('media') || []);\r\n \r\n drawerMediaItems.forEach((drawerMedia) => {\r\n if (drawerMedia.id === attributes.widgetId.value) {\r\n // Add drawer media to the region\r\n self.mediaObjectsActions.push(Media(\r\n self,\r\n drawerMedia?.getAttribute('id') || '',\r\n drawerMedia as Element,\r\n options as OptionsType & IRegion['options'],\r\n xlr,\r\n ));\r\n }\r\n });\r\n }\r\n });\r\n\r\n self.prepareMediaObjects();\r\n };\r\n\r\n regionObject.finished = function() {\r\n const self = regionObject;\r\n console.debug('Region::finished called . . . ', self.id);\r\n // Mark as complete\r\n self.complete = true;\r\n self.layout.regions[regionObject.index] = regionObject;\r\n self.layout.regionExpired();\r\n };\r\n\r\n regionObject.prepareMediaObjects = function() {\r\n const self = regionObject;\r\n let nextMediaIndex;\r\n\r\n if (self.mediaObjects.length > 0) {\r\n\r\n if (self.curMedia) {\r\n self.oldMedia = self.curMedia;\r\n } else {\r\n self.oldMedia = undefined;\r\n }\r\n\r\n if (self.currentMediaIndex >= self.mediaObjects.length) {\r\n self.currentMediaIndex = 0;\r\n }\r\n\r\n self.curMedia = self.mediaObjects[self.currentMediaIndex];\r\n\r\n nextMediaIndex = self.currentMediaIndex + 1;\r\n\r\n if (nextMediaIndex >= self.mediaObjects.length ||\r\n (\r\n !Boolean(self.mediaObjects[nextMediaIndex]) &&\r\n self.mediaObjects.length === 1\r\n )\r\n ) {\r\n nextMediaIndex = 0;\r\n }\r\n\r\n if (Boolean(self.mediaObjects[nextMediaIndex])) {\r\n self.nxtMedia = self.mediaObjects[nextMediaIndex];\r\n }\r\n\r\n const $region = document.getElementById(`${self.containerName}`);\r\n // Append available media to region DOM\r\n if (self.curMedia) {\r\n ($region) && $region.insertBefore(self.curMedia.html as Node, $region.lastElementChild);\r\n }\r\n\r\n if (self.nxtMedia) {\r\n ($region) && $region.insertBefore(self.nxtMedia.html as Node, $region.lastElementChild);\r\n }\r\n }\r\n };\r\n\r\n regionObject.run = function() {\r\n console.debug('Called Region::run > ', regionObject.id);\r\n\r\n // Reset region states\r\n regionObject.reset();\r\n\r\n if (regionObject.curMedia) {\r\n regionObject.transitionNodes(regionObject.oldMedia, regionObject.curMedia);\r\n }\r\n };\r\n\r\n regionObject.transitionNodes = function(oldMedia: IMedia | undefined, newMedia: IMedia | undefined) {\r\n const self = regionObject;\r\n let transOutDuration = 1;\r\n let transOutDirection: compassPoints = 'E';\r\n\r\n if (newMedia) {\r\n if (oldMedia && Boolean(oldMedia.options['transoutduration'])) {\r\n transOutDuration = Number(oldMedia.options.transoutduration);\r\n }\r\n\r\n if (oldMedia && Boolean(oldMedia.options['transoutdirection'])) {\r\n transOutDirection = oldMedia.options.transoutdirection;\r\n }\r\n \r\n let defaultTransOutOptions: TransitionElementOptions = {duration: transOutDuration};\r\n let transOut = transitionElement('defaultOut', {duration: defaultTransOutOptions.duration});\r\n \r\n let transOutName: TransitionNameType | string;\r\n if (oldMedia && Boolean(oldMedia.options['transout'])) {\r\n transOutName = oldMedia.options['transout'];\r\n \r\n if (transOutName === 'fly') {\r\n transOutName = `${transOutName}Out`;\r\n defaultTransOutOptions.keyframes = flyTransitionKeyframes({\r\n trans: 'out',\r\n direction: transOutDirection,\r\n height: oldMedia.divHeight,\r\n width: oldMedia.divWidth,\r\n });\r\n }\r\n \r\n transOut = transitionElement(transOutName as TransitionNameType, defaultTransOutOptions);\r\n }\r\n \r\n const hideOldMedia = new Promise((resolve) => {\r\n // Hide oldMedia\r\n if (oldMedia) {\r\n const $oldMedia = document.getElementById(getMediaId(oldMedia));\r\n if ($oldMedia) {\r\n const removeOldMedia = () => {\r\n $oldMedia.style.setProperty('display', 'none');\r\n $oldMedia.remove();\r\n };\r\n\r\n let oldMediaAnimate: any;\r\n if (Boolean(oldMedia.options['transout'])) {\r\n oldMediaAnimate = $oldMedia.animate(transOut.keyframes, transOut.timing);\r\n }\r\n\r\n if (Boolean(oldMedia.options['transout']) && self.totalMediaObjects > 1) {\r\n if (transOutName === 'flyOut') {\r\n // Reset last item to original position and state\r\n oldMediaAnimate ? oldMediaAnimate.finished\r\n .then(() => {\r\n resolve(true);\r\n oldMediaAnimate?.effect?.updateTiming({fill: 'none'});\r\n removeOldMedia();\r\n }) : undefined;\r\n } else {\r\n setTimeout(removeOldMedia, transOutDuration / 2);\r\n resolve(true);\r\n }\r\n } else {\r\n removeOldMedia();\r\n // Resolve this right away\r\n // As a result, the transition between two media object\r\n // seems like a cross-over\r\n resolve(true);\r\n\r\n }\r\n }\r\n }\r\n });\r\n \r\n if (oldMedia) {\r\n hideOldMedia.then((isDone) => {\r\n if (isDone) {\r\n newMedia.run();\r\n }\r\n });\r\n } else {\r\n newMedia.run();\r\n }\r\n }\r\n };\r\n\r\n regionObject.playNextMedia = function() {\r\n const self = regionObject;\r\n /* The current media has finished running */\r\n if (self.ended) {\r\n return;\r\n }\r\n\r\n if (self.currentMediaIndex === self.mediaObjects.length - 1) {\r\n self.finished();\r\n\r\n if (self.layout.allEnded) {\r\n return;\r\n }\r\n }\r\n\r\n // When the region has completed and when currentMedia is html\r\n // Then, preserve the currentMedia state\r\n if (self.complete &&\r\n self.curMedia?.render === 'html'\r\n ) {\r\n return;\r\n }\r\n\r\n // When the region has completed and mediaObjects.length = 1\r\n // and curMedia.loop = false, then put the media on\r\n // its current state\r\n if (self.complete && self.mediaObjects.length === 1 &&\r\n self.curMedia?.render !== 'html' &&\r\n self.curMedia?.mediaType === 'image' &&\r\n !self.curMedia?.loop\r\n ) {\r\n return;\r\n }\r\n\r\n self.currentMediaIndex = self.currentMediaIndex + 1;\r\n self.prepareMediaObjects();\r\n\r\n console.debug('region::playNextMedia', self);\r\n self.transitionNodes(self.oldMedia, self.curMedia);\r\n };\r\n \r\n regionObject.playPreviousMedia = function() {\r\n const self = regionObject;\r\n self.currentMediaIndex = self.currentMediaIndex - 1;\r\n\r\n if(self.currentMediaIndex < 0 || self.ended) {\r\n self.currentMediaIndex = 0;\r\n return;\r\n }\r\n\r\n self.prepareMediaObjects();\r\n\r\n console.debug('region::playPreviousMedia', self);\r\n /* Do the transition */\r\n self.transitionNodes(self.oldMedia, self.curMedia);\r\n };\r\n\r\n regionObject.end = function() {\r\n const self = regionObject;\r\n self.ending = true;\r\n /* The Layout has finished running */\r\n /* Do any region exit transition then clean up */\r\n self.layout.regions[self.index] = self;\r\n\r\n console.debug('Calling Region::end ', self);\r\n self.exitTransition();\r\n };\r\n\r\n regionObject.exitTransition = function() {\r\n const self = regionObject;\r\n /* TODO: Actually implement region exit transitions */\r\n const $region = document.getElementById(`${self.containerName}`);\r\n\r\n if ($region) {\r\n $region.style.display = 'none';\r\n }\r\n\r\n console.debug('Called Region::exitTransition ', self.id);\r\n\r\n self.exitTransitionComplete();\r\n };\r\n\r\n regionObject.exitTransitionComplete = function() {\r\n const self = regionObject;\r\n console.debug('Called Region::exitTransitionComplete ', self.id);\r\n self.ended = true;\r\n self.layout.regions[self.index] = self;\r\n self.layout.regionEnded();\r\n };\r\n\r\n regionObject.reset = function() {\r\n regionObject.ended = false;\r\n regionObject.complete = false;\r\n regionObject.ending = false;\r\n console.debug('Resetting region states', regionObject);\r\n };\r\n\r\n regionObject.on = function<E extends keyof IRegionEvents>(event: E, callback: IRegionEvents[E]) {\r\n return emitter.on(event, callback);\r\n };\r\n\r\n regionObject.emitter = emitter;\r\n\r\n regionObject.prepareRegion();\r\n\r\n return regionObject;\r\n}","var img = \"data:image/png;base64,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\";\n export default img;","var img = \"data:image/gif;base64,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\";\n export default img;","/*\r\n * Copyright (C) 2024 Xibo Signage Ltd\r\n *\r\n * Xibo - Digital Signage - https://www.xibosignage.com\r\n *\r\n * This file is part of Xibo.\r\n *\r\n * Xibo is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Lesser General Public License as published by\r\n * the Free Software Foundation, either version 3 of the License, or\r\n * any later version.\r\n *\r\n * Xibo is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Lesser General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Lesser General Public License\r\n * along with Xibo. If not, see <http://www.gnu.org/licenses/>.\r\n */\r\nimport Layout, { getLayout, getXlf, initRenderingDOM } from './Modules/Layout';\r\nimport { platform } from './Modules/Platform';\r\nimport {\r\n ILayout, initialLayout, InputLayoutType, OptionsType,\r\n} from './Types/Layout';\r\nimport { initialXlr, IXlr } from './Types/XLR';\r\nimport SplashScreen, {PreviewSplashElement} from './Modules/SplashScreen';\r\nimport {getIndexByLayoutId} from './Modules/Generators/Generators';\r\n\r\nexport default function XiboLayoutRenderer(\r\n inputLayouts: InputLayoutType[],\r\n options?: OptionsType,\r\n) {\r\n const props = {\r\n inputLayouts,\r\n options,\r\n }\r\n\r\n const xlrObject: IXlr = {\r\n ...initialXlr,\r\n };\r\n\r\n\r\n xlrObject.bootstrap = function() {\r\n // Place to set configurations and initialize required props\r\n const self = this;\r\n self.inputLayouts = !Array.isArray(props.inputLayouts) ?\r\n [props.inputLayouts] : props.inputLayouts;\r\n self.config = JSON.parse(JSON.stringify({...platform, ...props.options}));\r\n\r\n // Prepare rendering DOM\r\n const previewCanvas = document.querySelector('#preview_canvas');\r\n\r\n initRenderingDOM(previewCanvas);\r\n\r\n // Prepare splash screen\r\n const splashScreen = SplashScreen(\r\n document.querySelector('.player-preview'),\r\n self.config,\r\n );\r\n\r\n splashScreen.show();\r\n };\r\n xlrObject.init = function() {\r\n return new Promise<IXlr>((resolve) => {\r\n const self = this;\r\n\r\n // Check if only have splash screen from inputLayouts\r\n if (self.inputLayouts.length === 1 && self.inputLayouts[0].layoutId === 0) {\r\n resolve(self);\r\n } else {\r\n self.prepareLayouts().then((xlr) => {\r\n resolve(xlr);\r\n });\r\n }\r\n });\r\n };\r\n\r\n xlrObject.playSchedules = function(xlr: IXlr) {\r\n // Check if there's a current layout\r\n if (xlr.currentLayout !== undefined) {\r\n const $splashScreen = document.querySelector('.preview-splash') as PreviewSplashElement;\r\n if ($splashScreen && $splashScreen.style.display === 'block') {\r\n $splashScreen?.hide();\r\n }\r\n\r\n xlr.currentLayout.emitter.emit('start', xlr.currentLayout);\r\n xlr.currentLayout.run();\r\n }\r\n };\r\n\r\n xlrObject.updateLoop = function(inputLayouts: InputLayoutType[]) {\r\n this.updateLayouts(inputLayouts);\r\n };\r\n\r\n xlrObject.updateLayouts = async function(inputLayouts: InputLayoutType[]) {\r\n /**\r\n * @TODO\r\n * Case 1: If currentLayout in inputLayouts and in the same sequence,\r\n * Then, continue playing currentLayout.\r\n * Check nextLayout in inputLayouts. If in inputLayouts and same sequence, then don't change.\r\n * If not in inputLayouts, then replace and prepare nextLayout.\r\n *\r\n * Case 2: If currentLayout in inputLayouts but not in the same sequence,\r\n * Then, replace loop, prepare layouts and start currentLayout\r\n *\r\n * Case 3: If currentLayout not in inputLayouts,\r\n * Then, replace everything and start from first layout in sequence.\r\n */\r\n\r\n this.inputLayouts = inputLayouts;\r\n /** Case 1: When currentLayout is not in inputLayouts\r\n * Then, replace everything and start from first layout\r\n */\r\n if (inputLayouts.filter((inputLayout) => inputLayout.layoutId === this.currentLayout?.layoutId).length === 0) {\r\n // Unset currentLayout, nextLayout and layouts\r\n this.layouts = [];\r\n this.currentLayout = undefined;\r\n this.nextLayout = undefined;\r\n\r\n const xlr = await this.prepareLayouts();\r\n this.playSchedules(xlr);\r\n } else {\r\n /** Case 2: When currentLayout is in inputLayouts, then continue playing\r\n * Also check for nextLayout if in inputLayouts and same sequence, then don't change and continue playing.\r\n * If not in inputLayouts, then replace and prepare nextLayout.\r\n */\r\n\r\n // 2.1 We don't have to do anything for currentLayout\r\n // 2.2 Check for nextLayout\r\n // Get nextLayout index\r\n const currLayoutIndex = getIndexByLayoutId(inputLayouts, this.currentLayout?.layoutId).index as number;\r\n const nxtLayoutIndex = getIndexByLayoutId(inputLayouts, this.nextLayout?.layoutId).index as number;\r\n const tempOldNxtLayout = this.layouts[nxtLayoutIndex];\r\n let newNxtLayoutIndex = currLayoutIndex + 1;\r\n\r\n if (nxtLayoutIndex !== newNxtLayoutIndex) {\r\n // Delete old nextLayout\r\n delete this.layouts[nxtLayoutIndex];\r\n\r\n if (Boolean(this.layouts[newNxtLayoutIndex])) {\r\n this.nextLayout = this.layouts[newNxtLayoutIndex];\r\n this.layouts[newNxtLayoutIndex] = this.nextLayout;\r\n } else {\r\n // Check if newNxtLayoutIndex is still within inputLayouts\r\n if ((newNxtLayoutIndex + 1) > inputLayouts.length) {\r\n // Goes back to first layout in the sequence\r\n newNxtLayoutIndex = 0;\r\n }\r\n\r\n if (Boolean(inputLayouts[newNxtLayoutIndex])) {\r\n const tempNxtLayout = {...initialLayout, ...inputLayouts[newNxtLayoutIndex]};\r\n this.nextLayout = await this.prepareLayoutXlf(tempNxtLayout);\r\n this.layouts[newNxtLayoutIndex] = this.nextLayout;\r\n }\r\n\r\n // Move old nextLayout to its index\r\n let hasOldNxtLayout = inputLayouts\r\n .filter((_layout) => _layout.layoutId === tempOldNxtLayout?.layoutId);\r\n\r\n if (hasOldNxtLayout.length === 1) {\r\n const oldNxtLayoutIndex =\r\n getIndexByLayoutId(inputLayouts, hasOldNxtLayout[0].layoutId).index as number;\r\n this.layouts[oldNxtLayoutIndex] = tempOldNxtLayout;\r\n }\r\n }\r\n } else {\r\n // Check if newNxtLayout is not the same with nextLayout\r\n // Then, replace nextLayout with new one\r\n if (inputLayouts[nxtLayoutIndex].layoutId !== this.nextLayout?.layoutId) {\r\n const tempNewNxtLayout = {...initialLayout, ...inputLayouts[nxtLayoutIndex]};\r\n this.nextLayout = await this.prepareLayoutXlf(tempNewNxtLayout);\r\n this.layouts[nxtLayoutIndex] = this.nextLayout;\r\n }\r\n\r\n // Remove old nextLayout if it's not in inputLayouts\r\n if (tempOldNxtLayout?.index && Boolean(this.layouts[tempOldNxtLayout?.index])) {\r\n if (inputLayouts.filter((_layout) => _layout.layoutId === tempOldNxtLayout?.layoutId).length === 0) {\r\n delete this.layouts[tempOldNxtLayout?.index];\r\n }\r\n }\r\n }\r\n }\r\n };\r\n\r\n xlrObject.prepareLayouts = async function() {\r\n const self = this;\r\n // Get layouts\r\n const xlrLayouts = getLayout({xlr: self});\r\n\r\n console.debug('prepareLayouts::xlrLayouts', xlrLayouts);\r\n\r\n self.currentLayoutId = xlrLayouts.current?.layoutId as ILayout['layoutId'];\r\n\r\n const layoutsXlf = () => {\r\n let xlf = [];\r\n\r\n xlf.push(xlrLayouts.current);\r\n\r\n if (xlrLayouts.current?.layoutId !== xlrLayouts.next?.layoutId) {\r\n xlf.push(xlrLayouts.next);\r\n }\r\n\r\n return xlf.reduce((coll: Promise<ILayout>[], item) => {\r\n return [\r\n ...coll,\r\n self.prepareLayoutXlf(item),\r\n ];\r\n }, []);\r\n };\r\n const layouts = await Promise.all<Array<Promise<ILayout>>>(layoutsXlf());\r\n console.debug('prepareLayouts::layouts', layouts);\r\n console.debug('prepareLayouts::xlr>layouts', self.layouts);\r\n\r\n return new Promise<IXlr>((resolve) => {\r\n layouts.map((layoutItem) => {\r\n if (!Boolean(self.layouts[layoutItem.index])) {\r\n self.layouts[layoutItem.index] = layoutItem;\r\n }\r\n });\r\n self.currentLayoutIndex = xlrLayouts.currentLayoutIndex;\r\n self.currentLayout = self.layouts[self.currentLayoutIndex];\r\n\r\n if (Boolean(layouts[1])) {\r\n self.nextLayout = layouts[1];\r\n } else {\r\n // Use current layout as next layout if only one layout is available\r\n self.nextLayout = self.layouts[0];\r\n }\r\n\r\n self.layouts[self.currentLayoutIndex] = self.currentLayout;\r\n\r\n resolve(self);\r\n });\r\n };\r\n\r\n xlrObject.prepareLayoutXlf = async function(inputLayout: ILayout) {\r\n const self = this;\r\n // Compose layout props first\r\n let newOptions: OptionsType = Object.assign({}, platform);\r\n\r\n newOptions = {\r\n ...newOptions,\r\n ...props.options,\r\n };\r\n\r\n if (self.config.platform ==='CMS' &&\r\n inputLayout && Boolean(inputLayout.layoutId)\r\n ) {\r\n newOptions.xlfUrl =\r\n newOptions.xlfUrl.replace(':layoutId', String(inputLayout.layoutId));\r\n } else if (self.config.platform === 'chromeOS') {\r\n newOptions.xlfUrl = inputLayout.path as string;\r\n }\r\n\r\n let layoutXlf: string;\r\n let layoutXlfNode: Document | null;\r\n if (inputLayout && inputLayout.layoutNode === null) {\r\n layoutXlf = await getXlf(newOptions);\r\n\r\n const parser = new window.DOMParser();\r\n layoutXlfNode = parser.parseFromString(layoutXlf as string, 'text/xml');\r\n } else {\r\n layoutXlfNode = inputLayout && inputLayout.layoutNode;\r\n }\r\n\r\n return new Promise<ILayout>((resolve) => {\r\n const xlrLayoutObj = initialLayout;\r\n\r\n xlrLayoutObj.id = Number(inputLayout.layoutId);\r\n xlrLayoutObj.layoutId = Number(inputLayout.layoutId);\r\n xlrLayoutObj.options = newOptions;\r\n xlrLayoutObj.index = getIndexByLayoutId(this.inputLayouts, xlrLayoutObj.layoutId).index as number;\r\n\r\n resolve(Layout(layoutXlfNode, newOptions, self, xlrLayoutObj));\r\n });\r\n };\r\n\r\n xlrObject.bootstrap();\r\n\r\n return xlrObject;\r\n}\r\n","/*\r\n * Copyright (C) 2024 Xibo Signage Ltd\r\n *\r\n * Xibo - Digital Signage - https://www.xibosignage.com\r\n *\r\n * This file is part of Xibo.\r\n *\r\n * Xibo is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Lesser General Public License as published by\r\n * the Free Software Foundation, either version 3 of the License, or\r\n * any later version.\r\n *\r\n * Xibo is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Lesser General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Lesser General Public License\r\n * along with Xibo. If not, see <http://www.gnu.org/licenses/>.\r\n */\r\nimport './splash-screen.css';\r\nimport xiboLogoImg from './img/logo.png';\r\nimport loaderImg from './img/loader.gif';\r\nimport {OptionsType} from '../../Types/Layout';\r\n\r\nexport interface ISplashScreen {\r\n init: () => void;\r\n show: () => void;\r\n hide: () => void;\r\n}\r\n\r\nexport interface PreviewSplashElement extends HTMLDivElement {\r\n hide: () => void;\r\n}\r\n\r\nexport default function SplashScreen($parent: Element | null, config?: OptionsType): ISplashScreen {\r\n const $previewSplash = document.createElement('div') as PreviewSplashElement;\r\n const $previewLoader = document.createElement('div');\r\n const $previewLoaderCaption = document.createElement('div');\r\n const $defaultNoLayout = document.createElement('div');\r\n\r\n const splashScreenObj = {\r\n init() {\r\n $previewSplash.classList.add('preview-splash');\r\n\r\n // Don't show Xibo logo on CMS Preview\r\n if (config && config.platform !== 'CMS') {\r\n $previewSplash.style.setProperty(\r\n 'background-image',\r\n `url(${xiboLogoImg})`,\r\n );\r\n $previewSplash.style.setProperty(\r\n 'background-size',\r\n '200px 120px',\r\n );\r\n $previewSplash.style.setProperty(\r\n 'background-position',\r\n 'calc(100% - 50px) calc(100% - 30px)',\r\n );\r\n }\r\n\r\n $previewSplash.constructor.prototype.hide = () => {\r\n this.hide();\r\n };\r\n\r\n $previewLoader.classList.add('preview-loader');\r\n $previewLoaderCaption.classList.add('preview-loaderCaption');\r\n\r\n // Show loader bar and text on CMS Preview\r\n if (config && config.platform === 'CMS') {\r\n $previewLoader.style.setProperty(\r\n 'background-image',\r\n `url(${loaderImg})`,\r\n );\r\n $previewLoaderCaption.innerHTML = '<p>Loading Layout...</p>';\r\n }\r\n\r\n $previewSplash.insertBefore($previewLoader, $previewSplash.lastElementChild);\r\n $previewSplash.insertBefore($previewLoaderCaption, null);\r\n\r\n this.hide();\r\n },\r\n show() {\r\n if ($parent) {\r\n $parent.insertBefore($previewSplash, $parent.firstElementChild);\r\n $previewSplash.style.setProperty('display', 'block');\r\n }\r\n },\r\n hide() {\r\n $previewSplash.style.setProperty('display', 'none');\r\n },\r\n };\r\n\r\n splashScreenObj.init();\r\n\r\n return splashScreenObj;\r\n}\r\n"],"names":["createNanoEvents","emit","event","_len","arguments","length","args","Array","_key","i","callbacks","this","events","apply","on","cb","_this$events","_this","push","_this$events$event","filter","platform","getResourceUrl","xlfUrl","layoutBackgroundDownloadUrl","layoutPreviewUrl","libraryDownloadUrl","loaderUrl","idCounter","inPreview","appHost","initialLayout","id","layoutId","sw","sh","xw","xh","zIndex","scaleFactor","sWidth","sHeight","offsetX","offsetY","bgColor","bgImage","bgId","containerName","layoutNode","regionMaxZIndex","ready","regionObjects","drawer","allExpired","regions","actions","options","done","allEnded","path","prepareLayout","parseXlf","run","callback","regionExpired","end","regionEnded","stopAllMedia","Promise","resolve","resetLayout","emitter","index","actionController","undefined","nextId","getMediaId","_ref","mediaType","mediaId","capitalizeStr","inputStr","String","charAt","toUpperCase","substring","getDataBlob","_x","_getDataBlob","_asyncToGenerator","_regeneratorRuntime","mark","_callee","src","wrap","_context","prev","next","abrupt","fetch","mode","then","res","blob","rej","reader","FileReader","onloadend","result","onerror","readAsDataURL","stop","preloadMediaBlob","_x2","_x3","_preloadMediaBlob","_callee2","type","data","_context2","sent","Blob","arrayBuffer","audioFileType","filename","filenameArr","split","URL","createObjectURL","fetchJSON","_x4","_fetchJSON","_callee3","url","_context3","json","err","console","debug","str","validAudioTypes","mp3","wav","ogg","Boolean","getIndexByLayoutId","layoutsInput","layoutIndexes","reduce","a","b","indx","Number","_objectSpread","getAllAttributes","elem","getAttributeNames","obj","name","_defineProperty","value","getAttribute","initialRegion","layout","regionId","uniqueId","xml","mediaObjects","mediaObjectsActions","currentMedia","complete","ending","ended","oneMedia","oldMedia","curMedia","nxtMedia","currentMediaIndex","totalMediaObjects","prepareRegion","playNextMedia","playPreviousMedia","transitionNodes","finished","exitTransition","exitTransitionComplete","prepareMediaObjects","reset","initialMedia","region","html","iframe","iframeName","render","attachedAudio","singlePlay","timeoutId","setTimeout","checkIframeStatus","loadIframeOnRun","tempSrc","schemaVersion","duration","useDuration","fileId","uri","divWidth","divHeight","loop","init","defaultTrans","trans","keyframes","display","timing","fadeOutElem","opacity","fill","flyInElem","keyframeOptions","direction","flyInKeyframes","flyInTiming","from","to","flyOutElem","flyOutKeyframes","flyOutTiming","transitionElement","transition","fadeIn","fadeOut","flyIn","flyOut","defaultIn","defaultOut","flyTransitionKeyframes","params","opacityAttr","source","top","concat","height","left","width","Media","xlr","props","mediaTimer","mediaTimeCount","mediaObject","startMediaTimer","media","setInterval","$videoMedia","document","getElementById","onloadstart","onloadeddata","readyState","oncanplay","videoPlayPromise","play","error","muted","onplaying","ondurationchange","onended","_media$emitter","VideoMedia","$audioMedia","$playBtn","remove","audioPlayPromise","_$audioMedia$parentNo","createElement","classList","add","textContent","addEventListener","parentNode","insertBefore","nextSibling","AudioMedia","clearInterval","_self$xml","_self$xml2","_self$xml3","_self$xml4","_self$xml5","self","parseInt","$mediaIframe","mediaOptions","getElementsByTagName","_i","_Array$from","_mediaOptions","children","_i2","_Array$from2","mediaOption","nodeName","toLowerCase","showfullscreen","scrolling","style","cssText","$mediaId","$media","Audio","className","resourceUrlParams","config","regionOptions","isGlobalContent","isImageOrVideo","tmpUrl","resourceUrl","replace","composeResourceUrlByPlatform","_options$config","_options$config2","_options$config3","hardwareKey","cmsKey","composeResourceUrl","align","valign","preload","mute","scaletype","objectFit","playsInline","autoplay","regex","RegExp","exec","transInDuration","transinduration","fadeInTrans","animate","transInDirection","transindirection","defaultTransInOptions","transIn","transInName","showCurrentMedia","_ref2","isCMS","getNewMedia","setProperty","t0","t1","t2","t3","t4","call","t5","innerHTML","appendChild","$region","lastElementChild","Action","_createClass","_classCallCheck","ActionsWrapper","_HTMLDivElement","_callSuper","_inherits","_wrapNativeSuper","HTMLDivElement","customElements","define","extends","ELayoutType","ActionController","parent","$actionController","is","$actionListContainer","key","previewTranslations","window","translations","$container","$actionTitle","$actionsContainer","actionControllerTitle","firstElementChild","forEach","newAction","$newAction","attributes","Object","keys","attribKey","setAttribute","widgetId","layoutCode","target","$actionsToggler","querySelector","onclick","toggle","$webhookActions","querySelectorAll","$webhookAction","stopPropagation","runAction","dataset","confirm","navigateToLayout","open","actionType","regionObj","_targetRegion","_targetRegion2","_targetRegion3","targetRegion","targetMedia","splice","actionData","actiontype","openLayoutInNewTab","layoutcode","loadMediaInRegion","targetid","widgetid","log","nextMediaInRegion","$el","$sourceObj","_regionObjects","sourceid","_mediaObjects","ev","playAgainClickHandle","preventDefault","history","go","getXlf","_getXlf","_callee4","layoutOptions","apiHost","fetchOptions","_context4","location","origin","headers","text","getLayout","activeLayout","_currentLayout2","_currentLayout","_nextLayout","_params$xlr","inputLayouts","currentLayout","nextLayout","currLayoutIndx","currentLayoutIndex","hasLayout","nextLayoutIndex","nextLayoutTemp","layouts","current","Layout","$layout","prepareLayouts","playSchedules","layoutObject","$layoutContainer","$splashScreen","_layout$layoutNode","_layout$layoutNode2","_layout$layoutNode3","_layout$layoutNode4","_layout$layoutNode5","_layout$layoutNode6","_layout$layoutNode7","_layout$layoutNode8","$screen","outline","offsetWidth","offsetHeight","Math","min","abs","position","indexOf","bgImageUrl","composeBgUrlByPlatform","backgroundImage","backgroundRepeat","backgroundSize","backgroundPosition","backgroundColor","currentLayoutId","layoutActions","actionXml","layoutDrawers","layoutDrawerXml","layoutRegions","regionXml","regionObject","_self$xml6","_self$layout$actionCo","_regionOptions","regionOption","round","regionMediaItems","mediaXml","mediaObj","action","_self$layout$drawer","targetId","drawerMedia","nextMediaIndex","newMedia","transOutDuration","transOutDirection","transoutduration","transoutdirection","transOutName","defaultTransOutOptions","transOut","hideOldMedia","$oldMedia","oldMediaAnimate","removeOldMedia","_oldMediaAnimate","effect","updateTiming","isDone","_self$curMedia","_self$curMedia2","_self$curMedia3","_self$curMedia4","Region","initTouchActions","_step","_iterator","_createForOfIteratorHelper","s","n","e","f","$end","$preview","firstChild","removeChild","_step2","_iterator2","_ref3","j","exports","initialXlr","bootstrap","prepareLayoutXlf","inputLayout","updateLayouts","updateLoop","img","xlrObject","isArray","JSON","parse","stringify","_targetContainer","previewPlayer","previewScreen","endPlay","playAgainLink","previewCanvas","removeEventListener","body","$parent","$previewSplash","$previewLoader","$previewLoaderCaption","splashScreenObj","xiboLogoImg","constructor","prototype","hide","loaderImg","show","SplashScreen","_this$currentLayout","_this$nextLayout","currLayoutIndex","nxtLayoutIndex","tempOldNxtLayout","newNxtLayoutIndex","tempNxtLayout","hasOldNxtLayout","oldNxtLayoutIndex","_this$nextLayout2","tempNewNxtLayout","_this2","_this2$currentLayout","_layout","_xlrLayouts$current","xlrLayouts","layoutsXlf","_xlrLayouts$current2","_xlrLayouts$next","xlf","coll","item","_toConsumableArray","all","map","layoutItem","newOptions","layoutXlf","layoutXlfNode","parser","_this3","assign","DOMParser","parseFromString","xlrLayoutObj"],"mappings":"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","x_google_ignoreList":[0]}
|