@xibosignage/xibo-layout-renderer 1.0.1 → 1.0.2
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/Generators/Generators.d.ts +1 -0
- package/dist/xibo-layout-renderer.cjs.js +9 -1
- package/dist/xibo-layout-renderer.cjs.js.map +1 -1
- package/dist/xibo-layout-renderer.esm.js +9 -1
- package/dist/xibo-layout-renderer.esm.js.map +1 -1
- package/dist/xibo-layout-renderer.js +9 -1
- 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 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, 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\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 $layout.style.outline = 'red solid thin';\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,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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","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/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]}
|