{"version":3,"file":"vendors-98f38295.f584a1446b2fc034d810.bundle.js","mappings":"AAIA","sources":["webpack://lernplattform-admin-frontend/./node_modules/amazon-chime-sdk-js/build/task/TaskStatus.js","webpack://lernplattform-admin-frontend/./node_modules/amazon-chime-sdk-js/build/task/TimeoutTask.js","webpack://lernplattform-admin-frontend/./node_modules/amazon-chime-sdk-js/build/task/WaitForAttendeePresenceTask.js","webpack://lernplattform-admin-frontend/./node_modules/amazon-chime-sdk-js/build/transceivercontroller/DefaultTransceiverController.js","webpack://lernplattform-admin-frontend/./node_modules/amazon-chime-sdk-js/build/transceivercontroller/SimulcastContentShareTransceiverController.js","webpack://lernplattform-admin-frontend/./node_modules/amazon-chime-sdk-js/build/transceivercontroller/SimulcastTransceiverController.js","webpack://lernplattform-admin-frontend/./node_modules/amazon-chime-sdk-js/build/transceivercontroller/VideoOnlyTransceiverController.js","webpack://lernplattform-admin-frontend/./node_modules/amazon-chime-sdk-js/build/transcript/DefaultTranscriptionController.js","webpack://lernplattform-admin-frontend/./node_modules/amazon-chime-sdk-js/build/transcript/Transcript.js","webpack://lernplattform-admin-frontend/./node_modules/amazon-chime-sdk-js/build/transcript/TranscriptAlternative.js","webpack://lernplattform-admin-frontend/./node_modules/amazon-chime-sdk-js/build/transcript/TranscriptEntity.js","webpack://lernplattform-admin-frontend/./node_modules/amazon-chime-sdk-js/build/transcript/TranscriptEvent.js","webpack://lernplattform-admin-frontend/./node_modules/amazon-chime-sdk-js/build/transcript/TranscriptItem.js","webpack://lernplattform-admin-frontend/./node_modules/amazon-chime-sdk-js/build/transcript/TranscriptItemType.js","webpack://lernplattform-admin-frontend/./node_modules/amazon-chime-sdk-js/build/transcript/TranscriptLanguageWithScore.js","webpack://lernplattform-admin-frontend/./node_modules/amazon-chime-sdk-js/build/transcript/TranscriptResult.js","webpack://lernplattform-admin-frontend/./node_modules/amazon-chime-sdk-js/build/transcript/TranscriptionStatus.js","webpack://lernplattform-admin-frontend/./node_modules/amazon-chime-sdk-js/build/transcript/TranscriptionStatusType.js","webpack://lernplattform-admin-frontend/./node_modules/amazon-chime-sdk-js/build/useragentparser/DefaultUserAgentParser.js","webpack://lernplattform-admin-frontend/./node_modules/amazon-chime-sdk-js/build/utils/PromiseQueue.js","webpack://lernplattform-admin-frontend/./node_modules/amazon-chime-sdk-js/build/utils/Types.js","webpack://lernplattform-admin-frontend/./node_modules/amazon-chime-sdk-js/build/utils/Utils.js"],"sourcesContent":["\"use strict\";\n// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n// SPDX-License-Identifier: Apache-2.0\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar TaskStatus;\n(function (TaskStatus) {\n    TaskStatus[\"IDLE\"] = \"IDLE\";\n    TaskStatus[\"RUNNING\"] = \"RUNNING\";\n    TaskStatus[\"CANCELED\"] = \"CANCELED\";\n    TaskStatus[\"FINISHED\"] = \"FINISHED\";\n})(TaskStatus || (TaskStatus = {}));\nexports.default = TaskStatus;\n//# sourceMappingURL=TaskStatus.js.map","\"use strict\";\n// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n// SPDX-License-Identifier: Apache-2.0\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n    return new (P || (P = Promise))(function (resolve, reject) {\n        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n        function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n        step((generator = generator.apply(thisArg, _arguments || [])).next());\n    });\n};\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n    return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nconst TimeoutScheduler_1 = __importDefault(require(\"../scheduler/TimeoutScheduler\"));\nconst BaseTask_1 = __importDefault(require(\"./BaseTask\"));\n/**\n * [[TimeoutTask]] runs a subtask until it either succeeds or reaches a\n * timeout, at which point the subtask is canceled.\n */\nclass TimeoutTask extends BaseTask_1.default {\n    constructor(logger, taskToRunBeforeTimeout, timeoutMs) {\n        super(logger);\n        this.taskToRunBeforeTimeout = taskToRunBeforeTimeout;\n        this.timeoutMs = timeoutMs;\n        this.taskName = `Timeout${this.timeoutMs}ms`;\n        taskToRunBeforeTimeout.setParent(this);\n    }\n    cancel() {\n        this.logger.info(`canceling timeout task ${this.name()} subtask ${this.taskToRunBeforeTimeout}`);\n        this.taskToRunBeforeTimeout.cancel();\n    }\n    run() {\n        return __awaiter(this, void 0, void 0, function* () {\n            const timer = new TimeoutScheduler_1.default(this.timeoutMs);\n            timer.start(() => {\n                this.logger.info(`timeout reached for task ${this.name()}`);\n                this.taskToRunBeforeTimeout.cancel();\n            });\n            try {\n                yield this.taskToRunBeforeTimeout.run();\n            }\n            finally {\n                timer.stop();\n            }\n            this.logger.info(`timeout task ${this.name()} completed`);\n        });\n    }\n}\nexports.default = TimeoutTask;\n//# sourceMappingURL=TimeoutTask.js.map","\"use strict\";\n// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n// SPDX-License-Identifier: Apache-2.0\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n    return new (P || (P = Promise))(function (resolve, reject) {\n        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n        function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n        step((generator = generator.apply(thisArg, _arguments || [])).next());\n    });\n};\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n    return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nconst MeetingSessionStatusCode_1 = __importDefault(require(\"../meetingsession/MeetingSessionStatusCode\"));\nconst BaseTask_1 = __importDefault(require(\"./BaseTask\"));\n/*\n * [[WaitForAttendeePresenceTask]] waits until an attendee presence event happens.\n */\nclass WaitForAttendeePresenceTask extends BaseTask_1.default {\n    constructor(context) {\n        super(context.logger);\n        this.context = context;\n        this.taskName = 'WaitForAttendeePresenceTask';\n    }\n    cancel() {\n        // Just in case. The baseCancel behavior should prevent this.\n        /* istanbul ignore else */\n        if (this.cancelPromise) {\n            const error = new Error(`canceling ${this.name()} due to the meeting status code: ${MeetingSessionStatusCode_1.default.NoAttendeePresent}`);\n            this.cancelPromise(error);\n            delete this.cancelPromise;\n        }\n    }\n    run() {\n        return __awaiter(this, void 0, void 0, function* () {\n            const attendeeId = this.context.meetingSessionConfiguration.credentials.attendeeId;\n            return new Promise((resolve, reject) => {\n                const handler = (presentAttendeeId, present, _externalUserId, _dropped, _pos) => {\n                    if (attendeeId === presentAttendeeId && present) {\n                        this.context.realtimeController.realtimeUnsubscribeToAttendeeIdPresence(handler);\n                        resolve();\n                        delete this.cancelPromise;\n                    }\n                };\n                this.cancelPromise = (error) => {\n                    this.context.realtimeController.realtimeUnsubscribeToAttendeeIdPresence(handler);\n                    reject(error);\n                };\n                this.context.realtimeController.realtimeSubscribeToAttendeeIdPresence(handler);\n            });\n        });\n    }\n}\nexports.default = WaitForAttendeePresenceTask;\n//# sourceMappingURL=WaitForAttendeePresenceTask.js.map","\"use strict\";\n// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n// SPDX-License-Identifier: Apache-2.0\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n    return new (P || (P = Promise))(function (resolve, reject) {\n        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n        function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n        step((generator = generator.apply(thisArg, _arguments || [])).next());\n    });\n};\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n    return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nconst AudioProfile_1 = __importDefault(require(\"../audioprofile/AudioProfile\"));\nconst RedundantAudioRecoveryMetricReport_1 = __importDefault(require(\"../clientmetricreport/RedundantAudioRecoveryMetricReport\"));\nconst RedundantAudioEncoder_1 = __importDefault(require(\"../redundantaudioencoder/RedundantAudioEncoder\"));\nconst RedundantAudioEncoderWorkerCode_1 = __importDefault(require(\"../redundantaudioencoderworkercode/RedundantAudioEncoderWorkerCode\"));\nconst AsyncScheduler_1 = __importDefault(require(\"../scheduler/AsyncScheduler\"));\nclass DefaultTransceiverController {\n    constructor(logger, browserBehavior, meetingSessionContext) {\n        this.logger = logger;\n        this.browserBehavior = browserBehavior;\n        this.meetingSessionContext = meetingSessionContext;\n        this._localCameraTransceiver = null;\n        this._localAudioTransceiver = null;\n        this.videoSubscriptions = [];\n        this.defaultMediaStream = null;\n        this.peer = null;\n        this.streamIdToTransceiver = new Map();\n        this.groupIdToTransceiver = new Map();\n        this.audioRedWorker = null;\n        this.audioRedWorkerURL = null;\n        this.audioMetricsHistory = new Array();\n        this.redMetricsObservers = new Set();\n        this.currentNumRedundantEncodings = 0;\n        this.lastRedHolddownTimerStartTimestampMs = 0;\n        this.lastHighPacketLossEventTimestampMs = 0;\n        this.lastAudioRedTurnOffTimestampMs = 0;\n        this.maxAudioMetricsHistory = 20;\n        this.audioRedPacketLossShortEvalPeriodMs = 5 * 1000; // 5s\n        this.audioRedPacketLossLongEvalPeriodMs = 15 * 1000; // 15s\n        this.audioRedHoldDownTimeMs = 5 * 60 * 1000; // 5m\n        this.redRecoveryTimeMs = 1 * 60 * 1000; // 1m\n    }\n    setEncodingParameters(encodingParamMap) {\n        return __awaiter(this, void 0, void 0, function* () {\n            if (!this._localCameraTransceiver || this._localCameraTransceiver.direction !== 'sendrecv') {\n                return;\n            }\n            const sender = this._localCameraTransceiver.sender;\n            if (!encodingParamMap || encodingParamMap.size === 0) {\n                return;\n            }\n            const newEncodingParams = Array.from(encodingParamMap.values());\n            const oldParam = sender.getParameters();\n            if (!oldParam.encodings || oldParam.encodings.length === 0) {\n                oldParam.encodings = newEncodingParams;\n            }\n            else {\n                for (const existing of oldParam.encodings) {\n                    for (const changed of newEncodingParams) {\n                        if ((existing.rid || changed.rid) && existing.rid !== changed.rid) {\n                            continue;\n                        }\n                        let key;\n                        for (key in changed) {\n                            // These properties can't be changed.\n                            if (key === 'rid' || key === 'codecPayloadType') {\n                                continue;\n                            }\n                            /* istanbul ignore else */\n                            if (changed.hasOwnProperty(key)) {\n                                existing[key] = changed[key];\n                            }\n                        }\n                    }\n                }\n            }\n            yield sender.setParameters(oldParam);\n        });\n    }\n    localAudioTransceiver() {\n        return this._localAudioTransceiver;\n    }\n    localVideoTransceiver() {\n        return this._localCameraTransceiver;\n    }\n    setVideoSendingBitrateKbps(bitrateKbps) {\n        return __awaiter(this, void 0, void 0, function* () {\n            if (!this._localCameraTransceiver || this._localCameraTransceiver.direction !== 'sendrecv') {\n                return;\n            }\n            const sender = this._localCameraTransceiver.sender;\n            if (!sender || bitrateKbps <= 0) {\n                return;\n            }\n            const param = sender.getParameters();\n            if (!param.encodings) {\n                param.encodings = [{}];\n            }\n            for (const encodeParam of param.encodings) {\n                encodeParam.maxBitrate = bitrateKbps * 1000;\n            }\n            yield sender.setParameters(param);\n        });\n    }\n    setPeer(peer) {\n        this.peer = peer;\n    }\n    reset() {\n        this.destroyAudioRedWorkerAndStates();\n        this._localCameraTransceiver = null;\n        this._localAudioTransceiver = null;\n        this.videoSubscriptions = [];\n        this.defaultMediaStream = null;\n        this.peer = null;\n    }\n    useTransceivers() {\n        return !!this.peer && typeof this.peer.getTransceivers !== 'undefined';\n    }\n    hasVideoInput() {\n        if (!this._localCameraTransceiver || this._localCameraTransceiver.direction !== 'sendrecv')\n            return false;\n        return true;\n    }\n    trackIsVideoInput(track) {\n        if (!this._localCameraTransceiver) {\n            return false;\n        }\n        return (track === this._localCameraTransceiver.sender.track ||\n            track === this._localCameraTransceiver.receiver.track);\n    }\n    setupLocalTransceivers() {\n        var _a, _b;\n        if (!this.useTransceivers()) {\n            return;\n        }\n        if (!this.defaultMediaStream && typeof MediaStream !== 'undefined') {\n            this.defaultMediaStream = new MediaStream();\n        }\n        if (!this._localAudioTransceiver) {\n            this._localAudioTransceiver = this.peer.addTransceiver('audio', {\n                direction: 'inactive',\n                streams: [this.defaultMediaStream],\n            });\n            if ((_b = (_a = this.meetingSessionContext) === null || _a === void 0 ? void 0 : _a.audioProfile) === null || _b === void 0 ? void 0 : _b.hasRedundancyEnabled()) {\n                // This will perform additional necessary setup for the audio transceiver.\n                this.setupAudioRedWorker();\n            }\n        }\n        if (!this._localCameraTransceiver) {\n            this._localCameraTransceiver = this.addTransceiver('video', {\n                direction: 'inactive',\n                streams: [this.defaultMediaStream],\n            });\n        }\n    }\n    replaceAudioTrack(track) {\n        return __awaiter(this, void 0, void 0, function* () {\n            if (!this._localAudioTransceiver || this._localAudioTransceiver.direction !== 'sendrecv') {\n                this.logger.info(`audio transceiver direction is not set up or not activated`);\n                return false;\n            }\n            yield this._localAudioTransceiver.sender.replaceTrack(track);\n            return true;\n        });\n    }\n    setAudioInput(track) {\n        return __awaiter(this, void 0, void 0, function* () {\n            yield this.setTransceiverInput(this._localAudioTransceiver, track);\n            return;\n        });\n    }\n    setVideoInput(track) {\n        return __awaiter(this, void 0, void 0, function* () {\n            yield this.setTransceiverInput(this._localCameraTransceiver, track);\n            return;\n        });\n    }\n    updateVideoTransceivers(videoStreamIndex, videosToReceive) {\n        if (!this.useTransceivers()) {\n            return videosToReceive.array();\n        }\n        // See https://blog.mozilla.org/webrtc/rtcrtptransceiver-explored/ for details on transceivers\n        const transceivers = this.peer.getTransceivers();\n        // Subscription index 0 is reserved for transmitting camera.\n        // We mark inactive slots with 0 in the subscription array.\n        this.videoSubscriptions = [0];\n        videosToReceive = videosToReceive.clone();\n        this.updateTransceivers(transceivers, videoStreamIndex, videosToReceive);\n        this.logger.debug(() => {\n            return this.debugDumpTransceivers();\n        });\n        return this.videoSubscriptions;\n    }\n    updateTransceivers(transceivers, videoStreamIndex, videosToReceive) {\n        const videosRemaining = videosToReceive.array();\n        if (transceivers.length !== 0 && !transceivers[0].stop) {\n            // This function and its usage can be removed once we raise Chrome browser requirements\n            // to M88 (when `RTCRtpTransceiver.stop` was added)\n            this.logger.info('Updating transceivers without `stop` function');\n            this.updateTransceiverWithoutStop(transceivers, videoStreamIndex, videosRemaining);\n        }\n        else if (transceivers.length !== 0) {\n            this.updateTransceiverWithStop(transceivers, videoStreamIndex, videosRemaining);\n        }\n        // Add transceivers for the remaining subscriptions\n        for (const index of videosRemaining) {\n            // @ts-ignore\n            const transceiver = this.addTransceiver('video', {\n                direction: 'recvonly',\n                streams: [new MediaStream()],\n            });\n            this.streamIdToTransceiver.set(index, transceiver);\n            this.groupIdToTransceiver.set(videoStreamIndex.groupIdForStreamId(index), transceiver);\n            this.videoSubscriptions.push(index);\n            this.logger.info(`adding transceiver mid: ${transceiver.mid} subscription: ${index} direction: recvonly`);\n        }\n    }\n    updateTransceiverWithStop(transceivers, videoStreamIndex, videosRemaining) {\n        // Begin counting out index in the the subscription array at 1 since the camera.\n        // Always occupies position 0 (whether active or not).\n        let n = 1;\n        // Reset since otherwise there will be stale indexes corresponding to\n        // stopped transceivers.\n        this.videoSubscriptions = [0];\n        for (const transceiver of transceivers) {\n            if (transceiver === this._localCameraTransceiver ||\n                !this.transceiverIsVideo(transceiver) ||\n                !transceiver.mid) {\n                continue;\n            }\n            let reusingTranceiver = false;\n            // See if we want this existing transceiver for a simulcast stream switch\n            //\n            // By convention with the service backend, msid is equal to the media section mid, prefixed with the string \"v_\";\n            // we use this to get the stream ID for the track\n            const streamId = videoStreamIndex.streamIdForTrack('v_' + transceiver.mid);\n            if (transceiver.direction !== 'inactive' && streamId !== undefined) {\n                for (const [index, recvStreamId] of videosRemaining.entries()) {\n                    // `streamId` may still be the same as `recvStreamId`\n                    if (videoStreamIndex.StreamIdsInSameGroup(streamId, recvStreamId)) {\n                        transceiver.direction = 'recvonly';\n                        this.videoSubscriptions[n] = recvStreamId;\n                        reusingTranceiver = true;\n                        this.streamIdToTransceiver.delete(streamId);\n                        this.streamIdToTransceiver.set(recvStreamId, transceiver);\n                        videosRemaining.splice(index, 1);\n                        break;\n                    }\n                }\n            }\n            if (!reusingTranceiver) {\n                this.videoSubscriptions[n] = 0;\n                this.logger.info(`Stopping MID: ${transceiver.mid}, direction: ${transceiver.direction}, current direction: ${transceiver.currentDirection}`);\n                // Clean up transceiver and mappings for streams that have been unsubscribed from.  Note we do not try to reuse\n                // old inactive transceivers for new streams as Firefox will reuse the last frame from\n                // that transceiver, and additionally we simply don't want to risk wiring up a transceiver\n                // to the incorrect video stream for no real benefit besides possible a smaller SDP size.\n                transceiver.stop(); // Note (as of Firefox 94): Firefox will keep these around forever\n                for (const [streamId, previousTransceiver] of this.streamIdToTransceiver.entries()) {\n                    if (transceiver.mid === previousTransceiver.mid) {\n                        this.streamIdToTransceiver.delete(streamId);\n                        this.groupIdToTransceiver.delete(videoStreamIndex.groupIdForStreamId(streamId));\n                    }\n                }\n            }\n            n += 1;\n        }\n    }\n    // This function operates similarily to `updateTransceiverWithStop` with the following changes to account\n    // for the fact RTCRtpTransceiver.stop is not available on all supported browsers:\n    //  * We attempt to reuse inactive transceivers because libwebrtc will not remove them otherwise and\n    //    the SDP will grow endlessly.\n    //  * We mark unsubscribed transceivers as 'inactive' so that they can be reused. This requires using a\n    //    second for loop.\n    updateTransceiverWithoutStop(transceivers, videoStreamIndex, videosRemaining) {\n        let n = 1;\n        for (const transceiver of transceivers) {\n            if (transceiver === this._localCameraTransceiver || !this.transceiverIsVideo(transceiver)) {\n                continue;\n            }\n            this.videoSubscriptions[n] = 0;\n            if (transceiver.direction !== 'inactive') {\n                const streamId = videoStreamIndex.streamIdForTrack('v_' + transceiver.mid);\n                if (streamId !== undefined) {\n                    for (const [index, recvStreamId] of videosRemaining.entries()) {\n                        if (videoStreamIndex.StreamIdsInSameGroup(streamId, recvStreamId)) {\n                            transceiver.direction = 'recvonly';\n                            this.videoSubscriptions[n] = recvStreamId;\n                            this.streamIdToTransceiver.delete(streamId);\n                            this.streamIdToTransceiver.set(recvStreamId, transceiver);\n                            videosRemaining.splice(index, 1);\n                            break;\n                        }\n                    }\n                }\n            }\n            n += 1;\n        }\n        // Next fill in open slots and remove unused\n        n = 1;\n        for (const transceiver of transceivers) {\n            if (transceiver === this._localCameraTransceiver || !this.transceiverIsVideo(transceiver)) {\n                continue;\n            }\n            if (transceiver.direction === 'inactive' && videosRemaining.length > 0) {\n                // Fill available slot\n                transceiver.direction = 'recvonly';\n                const streamId = videosRemaining.shift();\n                this.videoSubscriptions[n] = streamId;\n                this.streamIdToTransceiver.set(streamId, transceiver);\n                this.groupIdToTransceiver.set(videoStreamIndex.groupIdForStreamId(streamId), transceiver);\n            }\n            else {\n                // Remove if no longer subscribed\n                if (this.videoSubscriptions[n] === 0) {\n                    transceiver.direction = 'inactive';\n                    for (const [streamId, previousTransceiver] of this.streamIdToTransceiver.entries()) {\n                        if (transceiver === previousTransceiver) {\n                            this.streamIdToTransceiver.delete(streamId);\n                            this.groupIdToTransceiver.delete(videoStreamIndex.groupIdForStreamId(streamId));\n                        }\n                    }\n                }\n            }\n            n += 1;\n        }\n    }\n    getMidForStreamId(streamId) {\n        var _a;\n        return (_a = this.streamIdToTransceiver.get(streamId)) === null || _a === void 0 ? void 0 : _a.mid;\n    }\n    setStreamIdForMid(mid, newStreamId) {\n        for (const [streamId, transceiver] of this.streamIdToTransceiver.entries()) {\n            if (transceiver.mid === mid) {\n                this.streamIdToTransceiver.delete(streamId);\n                this.streamIdToTransceiver.set(newStreamId, transceiver);\n                return;\n            }\n        }\n    }\n    getMidForGroupId(groupId) {\n        var _a, _b;\n        return (_b = (_a = this.groupIdToTransceiver.get(groupId)) === null || _a === void 0 ? void 0 : _a.mid) !== null && _b !== void 0 ? _b : undefined;\n    }\n    transceiverIsVideo(transceiver) {\n        return ((transceiver.receiver &&\n            transceiver.receiver.track &&\n            transceiver.receiver.track.kind === 'video') ||\n            (transceiver.sender && transceiver.sender.track && transceiver.sender.track.kind === 'video'));\n    }\n    debugDumpTransceivers() {\n        let msg = '';\n        let n = 0;\n        for (const transceiver of this.peer.getTransceivers()) {\n            if (!this.transceiverIsVideo(transceiver)) {\n                continue;\n            }\n            msg += `transceiver index=${n} mid=${transceiver.mid} subscription=${this.videoSubscriptions[n]} direction=${transceiver.direction}\\n`;\n            n += 1;\n        }\n        return msg;\n    }\n    setTransceiverInput(transceiver, track) {\n        return __awaiter(this, void 0, void 0, function* () {\n            if (!transceiver) {\n                return;\n            }\n            if (track) {\n                transceiver.direction = 'sendrecv';\n            }\n            else {\n                transceiver.direction = 'inactive';\n            }\n            yield transceiver.sender.replaceTrack(track);\n        });\n    }\n    forEachRedMetricsObserver(redMetricReport) {\n        for (const observer of this.redMetricsObservers) {\n            AsyncScheduler_1.default.nextTick(() => {\n                /* istanbul ignore else */\n                // Since this executes asynchronously, we need to check if the observer has not been removed.\n                if (this.redMetricsObservers.has(observer)) {\n                    observer.recoveryMetricsDidReceive(redMetricReport);\n                }\n            });\n        }\n    }\n    disableAudioRedundancy() {\n        // Reset the audio profile with the configured bitrate and force redundancy to be false.\n        this.meetingSessionContext.audioProfile = new AudioProfile_1.default(this.meetingSessionContext.audioProfile.audioBitrateBps, false);\n        this.meetingSessionContext.audioVideoController.setAudioProfile(this.meetingSessionContext.audioProfile);\n    }\n    setupAudioRedWorker() {\n        var _a, _b;\n        // @ts-ignore\n        const supportsRTCScriptTransform = !!window.RTCRtpScriptTransform;\n        // @ts-ignore\n        const supportsInsertableStreams = !!RTCRtpSender.prototype.createEncodedStreams;\n        if (supportsRTCScriptTransform) {\n            // This is the prefered approach according to\n            // https://github.com/w3c/webrtc-encoded-transform/blob/main/explainer.md.\n            this.logger.info('[AudioRed] Supports encoded insertable streams using RTCRtpScriptTransform');\n        }\n        else if (supportsInsertableStreams) {\n            this.logger.info('[AudioRed] Supports encoded insertable streams using TransformStream');\n        }\n        else {\n            this.disableAudioRedundancy();\n            // We need to recreate the peer connection without encodedInsertableStreams in the\n            // peer connection config otherwise we would need to create pass through transforms\n            // for all media streams. Throwing the error here and having AttackMediaInputTask throw the\n            // error again will result in a full reconnect.\n            throw new Error('[AudioRed] Encoded insertable streams not supported. Recreating peer connection with audio redundancy disabled.');\n        }\n        // Run the entire redundant audio worker setup in a `try` block to allow any errors to trigger a reconnect with\n        // audio redundancy disabled.\n        try {\n            this.audioRedWorkerURL = URL.createObjectURL(new Blob([RedundantAudioEncoderWorkerCode_1.default], {\n                type: 'application/javascript',\n            }));\n            this.logger.info(`[AudioRed] Redundant audio worker URL ${this.audioRedWorkerURL}`);\n            this.audioRedWorker = new Worker(this.audioRedWorkerURL);\n        }\n        catch (error) {\n            this.logger.error(`[AudioRed] Unable to create audio red worker due to ${error}`);\n            URL.revokeObjectURL(this.audioRedWorkerURL);\n            this.audioRedWorkerURL = null;\n            this.audioRedWorker = null;\n            this.disableAudioRedundancy();\n            this.logger.info(`[AudioRed] Recreating peer connection with audio redundancy disabled`);\n            // We need to recreate the peer connection without encodedInsertableStreams in the\n            // peer connection config otherwise we would need to create pass through transforms\n            // for all media streams. Throwing the error here and having AttackMediaInputTask throw the\n            // error again will result in a full reconnect.\n            throw error;\n        }\n        this.audioRedEnabled = true;\n        // We cannot use console.log in production code and we cannot\n        // transfer the logger object so we need the worker to post messages\n        // to the main thread for logging\n        this.audioRedWorker.onmessage = (event) => {\n            /* istanbul ignore else */\n            if (event.data.type === 'REDWorkerLog') {\n                this.logger.info(event.data.log);\n            } /* istanbul ignore next */\n            else if (event.data.type === 'RedundantAudioEncoderStats') {\n                const redMetricReport = new RedundantAudioRecoveryMetricReport_1.default();\n                redMetricReport.currentTimestampMs = Date.now();\n                redMetricReport.ssrc = event.data.ssrc;\n                redMetricReport.totalAudioPacketsLost = event.data.totalAudioPacketsLost;\n                redMetricReport.totalAudioPacketsExpected = event.data.totalAudioPacketsExpected;\n                redMetricReport.totalAudioPacketsRecoveredRed = event.data.totalAudioPacketsRecoveredRed;\n                redMetricReport.totalAudioPacketsRecoveredFec = event.data.totalAudioPacketsRecoveredFec;\n                this.forEachRedMetricsObserver(redMetricReport);\n            }\n        };\n        if (supportsRTCScriptTransform) {\n            // @ts-ignore\n            this._localAudioTransceiver.sender.transform = new RTCRtpScriptTransform(this.audioRedWorker, { type: 'SenderTransform' });\n            // @ts-ignore\n            this._localAudioTransceiver.receiver.transform = new RTCRtpScriptTransform(this.audioRedWorker, { type: 'ReceiverTransform' });\n            // eslint-disable-next-line\n        }\n        else /* istanbul ignore else */ if (supportsInsertableStreams) {\n            // @ts-ignore\n            const sendStreams = this._localAudioTransceiver.sender.createEncodedStreams();\n            // @ts-ignore\n            const receiveStreams = this._localAudioTransceiver.receiver.createEncodedStreams();\n            this.audioRedWorker.postMessage({\n                msgType: 'StartRedWorker',\n                send: sendStreams,\n                receive: receiveStreams,\n            }, [\n                sendStreams.readable,\n                sendStreams.writable,\n                receiveStreams.readable,\n                receiveStreams.writable,\n            ]);\n        }\n        /* istanbul ignore next */\n        (_a = this.meetingSessionContext) === null || _a === void 0 ? void 0 : _a.audioVideoController.addObserver(this);\n        /* istanbul ignore next */\n        this.addRedundantAudioRecoveryMetricsObserver((_b = this.meetingSessionContext) === null || _b === void 0 ? void 0 : _b.statsCollector);\n    }\n    /**\n     * Adds a transceiver to the peer connection and performs additional necessary setup.\n     */\n    addTransceiver(trackOrKind, init) {\n        var _a;\n        const transceiver = this.peer.addTransceiver(trackOrKind, init);\n        // @ts-ignore\n        // Transforms need to be setup for every transceiver to allow media flow for the given transceiver if WebRTC Encoded\n        // Transform (https://github.com/w3c/webrtc-encoded-transform/blob/main/explainer.md) is used.\n        if (!((_a = this.peer.getConfiguration()) === null || _a === void 0 ? void 0 : _a.encodedInsertableStreams) || !this.audioRedWorker)\n            return transceiver;\n        // @ts-ignore\n        const supportsRTCScriptTransform = !!window.RTCRtpScriptTransform;\n        // @ts-ignore\n        const supportsInsertableStreams = !!RTCRtpSender.prototype.createEncodedStreams;\n        if (supportsRTCScriptTransform) {\n            // @ts-ignore\n            transceiver.sender.transform = new RTCRtpScriptTransform(this.audioRedWorker, {\n                type: 'PassthroughTransform',\n            });\n            // @ts-ignore\n            transceiver.receiver.transform = new RTCRtpScriptTransform(this.audioRedWorker, {\n                type: 'PassthroughTransform',\n            });\n            // eslint-disable-next-line\n        }\n        else /* istanbul ignore else */ if (supportsInsertableStreams) {\n            // @ts-ignore\n            const sendStreams = transceiver.sender.createEncodedStreams();\n            // @ts-ignore\n            const receiveStreams = transceiver.receiver.createEncodedStreams();\n            this.audioRedWorker.postMessage({\n                msgType: 'PassthroughTransform',\n                send: sendStreams,\n                receive: receiveStreams,\n            }, [\n                sendStreams.readable,\n                sendStreams.writable,\n                receiveStreams.readable,\n                receiveStreams.writable,\n            ]);\n        }\n        return transceiver;\n    }\n    destroyAudioRedWorkerAndStates() {\n        var _a, _b;\n        if (this.audioRedWorker) {\n            URL.revokeObjectURL(this.audioRedWorkerURL);\n            this.audioRedWorkerURL = null;\n            this.audioRedWorker.terminate();\n            this.audioRedWorker = null;\n            this.currentNumRedundantEncodings = 0;\n            this.lastRedHolddownTimerStartTimestampMs = 0;\n            this.lastAudioRedTurnOffTimestampMs = 0;\n            this.lastHighPacketLossEventTimestampMs = 0;\n            this.audioRedEnabled = true;\n            /* istanbul ignore next */\n            (_a = this.meetingSessionContext) === null || _a === void 0 ? void 0 : _a.audioVideoController.removeObserver(this);\n            /* istanbul ignore next */\n            this.removeRedundantAudioRecoveryMetricsObserver((_b = this.meetingSessionContext) === null || _b === void 0 ? void 0 : _b.statsCollector);\n        }\n    }\n    setAudioPayloadTypes(payloadTypeMap) {\n        if (this.audioRedWorker) {\n            this.audioRedWorker.postMessage({\n                msgType: 'RedPayloadType',\n                payloadType: payloadTypeMap.get('red'),\n            });\n            this.audioRedWorker.postMessage({\n                msgType: 'OpusPayloadType',\n                payloadType: payloadTypeMap.get('opus'),\n            });\n        }\n    }\n    metricsDidReceive(clientMetricReport) {\n        const { currentTimestampMs } = clientMetricReport;\n        const rtcStatsReport = clientMetricReport.getRTCStatsReport();\n        let receiverReportReceptionTimestampMs = 0;\n        let currentTotalPacketsSent = 0;\n        let currentTotalPacketsLost = 0;\n        rtcStatsReport.forEach(report => {\n            /* istanbul ignore else */\n            if (report.kind === 'audio') {\n                /* istanbul ignore else */\n                if (report.type === 'outbound-rtp') {\n                    currentTotalPacketsSent = report.packetsSent;\n                } /* istanbul ignore else */\n                else if (report.type === 'remote-inbound-rtp') {\n                    // Use the timestamp that the receiver report was received on the client side to get a more accurate time\n                    // interval for the metrics.\n                    receiverReportReceptionTimestampMs = report.timestamp;\n                    currentTotalPacketsLost = report.packetsLost;\n                }\n            }\n        });\n        // Since the timestamp from the server side is only updated when a new receiver report is generated, only add\n        // metrics with new timestamps to our metrics history.\n        //\n        // Also, make sure that the total packets sent is greater than the most recent value in the history before consuming\n        // to avoid divide-by-zero while calculating uplink loss percent.\n        if (this.audioMetricsHistory.length === 0 ||\n            (receiverReportReceptionTimestampMs >\n                this.audioMetricsHistory[this.audioMetricsHistory.length - 1].timestampMs &&\n                currentTotalPacketsSent >\n                    this.audioMetricsHistory[this.audioMetricsHistory.length - 1].totalPacketsSent)) {\n            // Note that although the total packets sent is updated anytime we get the WebRTC stats, we are only adding a new\n            // metric for total packets sent when we receive a new receiver report. We only care about the total packets that\n            // the server was expected to receive at the time that the latest `packetsLost` metric was calculated in order to\n            // do our uplink loss calculation. Therefore, we only record the total packets sent when we receive a new receiver\n            // report, which will give us an estimate of the number of packets that the server was supposed to receive at the\n            // time when the latest `packetsLost` metric was calculated.\n            this.audioMetricsHistory.push({\n                timestampMs: receiverReportReceptionTimestampMs,\n                totalPacketsSent: currentTotalPacketsSent,\n                totalPacketsLost: currentTotalPacketsLost,\n            });\n        }\n        // Remove the oldest metric report from our list\n        if (this.audioMetricsHistory.length > this.maxAudioMetricsHistory) {\n            this.audioMetricsHistory.shift();\n        }\n        // As the minimum RTCP frequency is about 1 every 5 seconds,\n        // we are limited to using a minimum timewindow of 5 seconds.\n        // This is because the cumulative packetsLost metric remains\n        // the same for 5 consecutive client metric reports.\n        const lossPercent5sTimewindow = this.lossPercent(this.audioRedPacketLossShortEvalPeriodMs);\n        const lossPercent15sTimewindow = this.lossPercent(this.audioRedPacketLossLongEvalPeriodMs);\n        // Taking the max loss percent between a short and long time window will allow\n        // us to increase the number of encodings fast but will slowly decrease the\n        // number of encodings on loss recovery.\n        const maxLossPercent = Math.max(lossPercent5sTimewindow, lossPercent15sTimewindow);\n        const [newNumRedundantEncodings, shouldTurnOffRed,] = RedundantAudioEncoder_1.default.getNumRedundantEncodingsForPacketLoss(maxLossPercent);\n        if (shouldTurnOffRed) {\n            this.lastHighPacketLossEventTimestampMs = currentTimestampMs;\n            /* istanbul ignore next */\n            if (this.audioRedEnabled) {\n                if (this.audioRedWorker) {\n                    this.audioRedWorker.postMessage({\n                        msgType: 'Disable',\n                    });\n                }\n                this.audioRedEnabled = false;\n                this.lastAudioRedTurnOffTimestampMs = currentTimestampMs;\n            }\n            return;\n        }\n        else if (!this.audioRedEnabled) {\n            const timeSinceRedOff = currentTimestampMs - this.lastAudioRedTurnOffTimestampMs;\n            const timeSinceLastHighPacketLossEvent = currentTimestampMs - this.lastHighPacketLossEventTimestampMs;\n            if (timeSinceRedOff >= this.audioRedPacketLossLongEvalPeriodMs &&\n                timeSinceLastHighPacketLossEvent < this.redRecoveryTimeMs) {\n                // This is probably not a transient high packet loss spike.\n                // We need to turn off RED for awhile to avoid congestion collapse.\n                return;\n            }\n            else {\n                // Enable red as we've completed the recovery wait time.\n                /* istanbul ignore next */\n                if (this.audioRedWorker) {\n                    this.audioRedWorker.postMessage({\n                        msgType: 'Enable',\n                    });\n                }\n                this.audioRedEnabled = true;\n                this.maybeResetHoldDownTimer(currentTimestampMs);\n            }\n        }\n        if (this.shouldUpdateAudioRedWorkerEncodings(currentTimestampMs, newNumRedundantEncodings)) {\n            /* istanbul ignore next */\n            if (this.audioRedWorker) {\n                this.audioRedWorker.postMessage({\n                    msgType: 'UpdateNumRedundantEncodings',\n                    numRedundantEncodings: newNumRedundantEncodings,\n                });\n            }\n        }\n    }\n    maybeResetHoldDownTimer(currentTimestampMs) {\n        if (this.currentNumRedundantEncodings > 0) {\n            this.lastRedHolddownTimerStartTimestampMs = currentTimestampMs;\n        }\n    }\n    lossPercent(timeWindowMs) {\n        if (this.audioMetricsHistory.length < 2) {\n            return 0;\n        }\n        const latestReceiverReportTimestampMs = this.audioMetricsHistory[this.audioMetricsHistory.length - 1].timestampMs;\n        const currentTotalPacketsSent = this.audioMetricsHistory[this.audioMetricsHistory.length - 1].totalPacketsSent;\n        const currentTotalPacketsLost = this.audioMetricsHistory[this.audioMetricsHistory.length - 1].totalPacketsLost;\n        // Iterate backwards in the metrics history, from the report immediately preceeding\n        // the latest one, until we find the first metric report whose timestamp differs\n        // from the latest report by atleast timeWindowMs\n        for (let i = this.audioMetricsHistory.length - 2; i >= 0; i--) {\n            if (latestReceiverReportTimestampMs - this.audioMetricsHistory[i].timestampMs >=\n                timeWindowMs) {\n                const lossDelta = currentTotalPacketsLost - this.audioMetricsHistory[i].totalPacketsLost;\n                const sentDelta = currentTotalPacketsSent - this.audioMetricsHistory[i].totalPacketsSent;\n                const lossPercent = 100 * (lossDelta / sentDelta);\n                return Math.max(0, Math.min(lossPercent, 100));\n            }\n        }\n        // If we are here, we don't have enough entries in history\n        // to calculate the loss for the given time window\n        return 0;\n    }\n    shouldUpdateAudioRedWorkerEncodings(currentTimestampMs, newNumRedundantEncodings) {\n        // If newNumRedundantEncodings is the same as the current\n        // then we don't need to send a message to the red worker.\n        if (this.currentNumRedundantEncodings === newNumRedundantEncodings) {\n            this.maybeResetHoldDownTimer(currentTimestampMs);\n            return false;\n        }\n        // If newNumRedundantEncodings is less than the current\n        // check if we've cleared the hold down time and only\n        // then allow the update to be sent to the red worker\n        if (newNumRedundantEncodings < this.currentNumRedundantEncodings &&\n            currentTimestampMs - this.lastRedHolddownTimerStartTimestampMs < this.audioRedHoldDownTimeMs) {\n            return false;\n        }\n        this.currentNumRedundantEncodings = newNumRedundantEncodings;\n        this.maybeResetHoldDownTimer(currentTimestampMs);\n        return true;\n    }\n    addRedundantAudioRecoveryMetricsObserver(observer) {\n        this.redMetricsObservers.add(observer);\n    }\n    removeRedundantAudioRecoveryMetricsObserver(observer) {\n        this.redMetricsObservers.delete(observer);\n    }\n}\nexports.default = DefaultTransceiverController;\n//# sourceMappingURL=DefaultTransceiverController.js.map","\"use strict\";\n// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n// SPDX-License-Identifier: Apache-2.0\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n    return new (P || (P = Promise))(function (resolve, reject) {\n        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n        function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n        step((generator = generator.apply(thisArg, _arguments || [])).next());\n    });\n};\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n    return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nconst SimulcastTransceiverController_1 = __importDefault(require(\"./SimulcastTransceiverController\"));\nclass SimulcastContentShareTransceiverController extends SimulcastTransceiverController_1.default {\n    constructor(logger, browserBehavior, meetingSessionContext) {\n        super(logger, browserBehavior, meetingSessionContext);\n        let scale = 2;\n        this.videoQualityControlParameterMap = new Map();\n        for (let i = 0; i < SimulcastContentShareTransceiverController.NAME_ARR_ASCENDING.length; i++) {\n            const ridName = SimulcastContentShareTransceiverController.NAME_ARR_ASCENDING[i];\n            this.videoQualityControlParameterMap.set(ridName, {\n                rid: ridName,\n                scaleResolutionDownBy: scale,\n                maxBitrate: SimulcastContentShareTransceiverController.BITRATE_ARR_ASCENDING[i] * 1000,\n            });\n            scale = scale / 2;\n        }\n    }\n    // Note: `scaleResolutionDownBy` has only been tested with values 1, 2, and 4.\n    setEncodingParameters(encodingParamMap) {\n        return __awaiter(this, void 0, void 0, function* () {\n            if (!this._localCameraTransceiver || this._localCameraTransceiver.direction !== 'sendrecv') {\n                return;\n            }\n            const sender = this._localCameraTransceiver.sender;\n            const newEncodingParams = Array.from(encodingParamMap.values());\n            if (newEncodingParams.length <= 0) {\n                return;\n            }\n            const oldParam = sender.getParameters();\n            if (!oldParam.encodings) {\n                oldParam.encodings = newEncodingParams;\n            }\n            else {\n                for (let i = 0; i < oldParam.encodings.length; i++) {\n                    if (oldParam.encodings[i].rid === SimulcastTransceiverController_1.default.LOW_LEVEL_NAME) {\n                        this.copyEncodingParams(encodingParamMap.get(SimulcastTransceiverController_1.default.LOW_LEVEL_NAME), oldParam.encodings[i]);\n                    }\n                    if (oldParam.encodings[i].rid === SimulcastTransceiverController_1.default.HIGH_LEVEL_NAME) {\n                        this.copyEncodingParams(encodingParamMap.get(SimulcastTransceiverController_1.default.HIGH_LEVEL_NAME), oldParam.encodings[i]);\n                    }\n                }\n            }\n            yield sender.setParameters(oldParam);\n            this.logVideoTransceiverParameters();\n        });\n    }\n}\nexports.default = SimulcastContentShareTransceiverController;\nSimulcastContentShareTransceiverController.NAME_ARR_ASCENDING = ['low', 'hi'];\nSimulcastContentShareTransceiverController.BITRATE_ARR_ASCENDING = [300, 1200];\n//# sourceMappingURL=SimulcastContentShareTransceiverController.js.map","\"use strict\";\n// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n// SPDX-License-Identifier: Apache-2.0\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n    return new (P || (P = Promise))(function (resolve, reject) {\n        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n        function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n        step((generator = generator.apply(thisArg, _arguments || [])).next());\n    });\n};\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n    return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nconst DefaultTransceiverController_1 = __importDefault(require(\"./DefaultTransceiverController\"));\nclass SimulcastTransceiverController extends DefaultTransceiverController_1.default {\n    constructor(logger, browserBehavior, meetingSessionContext) {\n        super(logger, browserBehavior, meetingSessionContext);\n        this.videoQualityControlParameterMap = new Map();\n        let scale = 4;\n        for (let i = 0; i < SimulcastTransceiverController.NAME_ARR_ASCENDING.length; i++) {\n            const ridName = SimulcastTransceiverController.NAME_ARR_ASCENDING[i];\n            this.videoQualityControlParameterMap.set(ridName, {\n                rid: ridName,\n                scaleResolutionDownBy: scale,\n                maxBitrate: SimulcastTransceiverController.BITRATE_ARR_ASCENDING[i] * 1000,\n            });\n            scale = scale / 2;\n        }\n    }\n    // Note: `scaleResolutionDownBy` has only been tested with values 1, 2, and 4.\n    setEncodingParameters(encodingParamMap) {\n        return __awaiter(this, void 0, void 0, function* () {\n            if (!this._localCameraTransceiver || this._localCameraTransceiver.direction !== 'sendrecv') {\n                return;\n            }\n            const sender = this._localCameraTransceiver.sender;\n            const newEncodingParams = Array.from(encodingParamMap.values());\n            if (newEncodingParams.length <= 0) {\n                return;\n            }\n            const oldParam = sender.getParameters();\n            if (!oldParam.encodings) {\n                oldParam.encodings = newEncodingParams;\n            }\n            else {\n                for (const encoding of oldParam.encodings) {\n                    if (encoding.rid === SimulcastTransceiverController.LOW_LEVEL_NAME) {\n                        this.copyEncodingParams(encodingParamMap.get(SimulcastTransceiverController.LOW_LEVEL_NAME), encoding);\n                    }\n                    if (encoding.rid === SimulcastTransceiverController.MID_LEVEL_NAME) {\n                        this.copyEncodingParams(encodingParamMap.get(SimulcastTransceiverController.MID_LEVEL_NAME), encoding);\n                    }\n                    if (encoding.rid === SimulcastTransceiverController.HIGH_LEVEL_NAME) {\n                        this.copyEncodingParams(encodingParamMap.get(SimulcastTransceiverController.HIGH_LEVEL_NAME), encoding);\n                    }\n                }\n            }\n            yield sender.setParameters(oldParam);\n            this.logVideoTransceiverParameters();\n        });\n    }\n    setVideoSendingBitrateKbps(_bitrateKbps) {\n        return __awaiter(this, void 0, void 0, function* () {\n            return;\n        });\n    }\n    setupLocalTransceivers() {\n        var _a, _b;\n        if (!this.useTransceivers()) {\n            return;\n        }\n        if (!this.defaultMediaStream && typeof MediaStream !== 'undefined') {\n            this.defaultMediaStream = new MediaStream();\n        }\n        if (!this._localAudioTransceiver) {\n            this._localAudioTransceiver = this.peer.addTransceiver('audio', {\n                direction: 'inactive',\n                streams: [this.defaultMediaStream],\n            });\n            if ((_b = (_a = this.meetingSessionContext) === null || _a === void 0 ? void 0 : _a.audioProfile) === null || _b === void 0 ? void 0 : _b.hasRedundancyEnabled()) {\n                // This will perform additional necessary setup for the audio transceiver.\n                this.setupAudioRedWorker();\n            }\n        }\n        if (!this._localCameraTransceiver) {\n            const encodingParams = Array.from(this.videoQualityControlParameterMap.values());\n            this._localCameraTransceiver = this.addTransceiver('video', {\n                direction: 'inactive',\n                streams: [this.defaultMediaStream],\n                sendEncodings: encodingParams,\n            });\n        }\n    }\n    logVideoTransceiverParameters() {\n        const params = this._localCameraTransceiver.sender.getParameters();\n        const encodings = params.encodings;\n        let msg = 'simulcast: current encoding parameters \\n';\n        for (const encodingParam of encodings) {\n            msg += `rid=${encodingParam.rid} maxBitrate=${encodingParam.maxBitrate} active=${encodingParam.active} scaleDownBy=${encodingParam.scaleResolutionDownBy} maxFrameRate = ${encodingParam.maxFramerate} \\n`;\n        }\n        this.logger.info(msg);\n    }\n    copyEncodingParams(fromEncodingParams, toEncodingParams) {\n        toEncodingParams.active = fromEncodingParams.active;\n        toEncodingParams.maxBitrate = fromEncodingParams.maxBitrate;\n        toEncodingParams.scaleResolutionDownBy = fromEncodingParams.scaleResolutionDownBy;\n        toEncodingParams.maxFramerate = fromEncodingParams.maxFramerate;\n    }\n}\nexports.default = SimulcastTransceiverController;\nSimulcastTransceiverController.LOW_LEVEL_NAME = 'low';\nSimulcastTransceiverController.MID_LEVEL_NAME = 'mid';\nSimulcastTransceiverController.HIGH_LEVEL_NAME = 'hi';\nSimulcastTransceiverController.NAME_ARR_ASCENDING = ['low', 'mid', 'hi'];\nSimulcastTransceiverController.BITRATE_ARR_ASCENDING = [200, 400, 1100];\n//# sourceMappingURL=SimulcastTransceiverController.js.map","\"use strict\";\n// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n// SPDX-License-Identifier: Apache-2.0\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n    return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nconst DefaultTransceiverController_1 = __importDefault(require(\"./DefaultTransceiverController\"));\nclass VideoOnlyTransceiverController extends DefaultTransceiverController_1.default {\n    constructor(logger, browserBehavior, meetingSessionContext) {\n        super(logger, browserBehavior, meetingSessionContext);\n    }\n    setupLocalTransceivers() {\n        if (!this.useTransceivers()) {\n            return;\n        }\n        if (!this.defaultMediaStream && typeof MediaStream !== 'undefined') {\n            this.defaultMediaStream = new MediaStream();\n        }\n        if (!this._localCameraTransceiver) {\n            this._localCameraTransceiver = this.peer.addTransceiver('video', {\n                direction: 'inactive',\n                streams: [this.defaultMediaStream],\n            });\n        }\n    }\n}\nexports.default = VideoOnlyTransceiverController;\n//# sourceMappingURL=VideoOnlyTransceiverController.js.map","\"use strict\";\n// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n// SPDX-License-Identifier: Apache-2.0\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.TRANSCRIPTION_DATA_MESSAGE_TOPIC = void 0;\nconst TranscriptEvent_1 = require(\"./TranscriptEvent\");\nexports.TRANSCRIPTION_DATA_MESSAGE_TOPIC = 'aws:chime:transcription';\nclass DefaultTranscriptionController {\n    constructor(realtimeController) {\n        this.realtimeController = realtimeController;\n        this.transcriptEventCallbacks = new Set();\n    }\n    subscribeToTranscriptEvent(callback) {\n        if (this.transcriptEventCallbacks.size === 0) {\n            this.realtimeController.realtimeSubscribeToReceiveDataMessage(exports.TRANSCRIPTION_DATA_MESSAGE_TOPIC, (dataMessage) => {\n                for (const transcriptEvent of TranscriptEvent_1.TranscriptEventConverter.from(dataMessage)) {\n                    for (const transcriptEventCallback of this.transcriptEventCallbacks) {\n                        transcriptEventCallback(transcriptEvent);\n                    }\n                }\n            });\n        }\n        this.transcriptEventCallbacks.add(callback);\n    }\n    unsubscribeFromTranscriptEvent(callback) {\n        this.transcriptEventCallbacks.delete(callback);\n        if (this.transcriptEventCallbacks.size === 0) {\n            this.realtimeController.realtimeUnsubscribeFromReceiveDataMessage(exports.TRANSCRIPTION_DATA_MESSAGE_TOPIC);\n        }\n    }\n}\nexports.default = DefaultTranscriptionController;\n//# sourceMappingURL=DefaultTranscriptionController.js.map","\"use strict\";\n// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n// SPDX-License-Identifier: Apache-2.0\nObject.defineProperty(exports, \"__esModule\", { value: true });\nclass Transcript {\n}\nexports.default = Transcript;\n//# sourceMappingURL=Transcript.js.map","\"use strict\";\n// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n// SPDX-License-Identifier: Apache-2.0\nObject.defineProperty(exports, \"__esModule\", { value: true });\nclass TranscriptAlternative {\n}\nexports.default = TranscriptAlternative;\n//# sourceMappingURL=TranscriptAlternative.js.map","\"use strict\";\n// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n// SPDX-License-Identifier: Apache-2.0\nObject.defineProperty(exports, \"__esModule\", { value: true });\n/*\n* When redacting personally identifiable information (PII) from a streaming transcription, Amazon Transcribe replaces each identified instance of PII with [PII] in your transcript.\n* An additional option available for streaming audio is PII identification.\n* When you activate PII Identification, Amazon Transcribe labels the PII in your transcription results under an Entities object.\n* PII identification and redaction for streaming jobs is performed only upon complete transcription of the audio segments.\n* category refers to whether the entity is a PII or PHI data.\n* confidence refers to the confidence that the speech it flagged for redaction/identification is truly PII. Confidence value ranges from 0 to 1 inclusive.\n* type refers to the type of PII/PHI data that is identified. The current supported type values are: BANK_ACCOUNT_NUMBER, BANK_ROUTING, CREDIT_DEBIT_NUMBER, CREDIT_DEBIT_CVV, CREDIT_DEBIT_EXPIRY, PIN, EMAIL, ADDRESS, NAME, PHONE, SSN.\n* type is only available in case of engine transcribe and not in medical transcribe\n* type can be expected to change and grow as Transcribe evolves\n* endTimeMs and startTimeMs are epoch timestamps in milliseconds\n* Sample Redacted PII Data would look similar to this :\n* \"Entities\": [\n                {\n                    \"Content\": \"[NAME]\",\n                    \"Category\": \"PII\",\n                    \"Type\": \"NAME\",\n                    \"StartTime\" : 1636493289421,\n                    \"EndTime\" : 1636493290016,\n                    \"Confidence\": 0.9989\n                }\n            ]\n* Sample PII Identified data would look similar to this :\n* \"Entities\": [\n                {\n                    \"Content\": \"janet smithy\",\n                    \"Category\": \"PII\",\n                    \"Type\": \"NAME\",\n                    \"StartTime\" : 1636493289421,\n                    \"EndTime\" : 1636493290016,\n                    \"Confidence\": 0.9989\n                }\n              ]\n*/\nclass TranscriptEntity {\n}\nexports.default = TranscriptEntity;\n//# sourceMappingURL=TranscriptEntity.js.map","\"use strict\";\n// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n// SPDX-License-Identifier: Apache-2.0\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n    return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.TranscriptEventConverter = void 0;\nconst SignalingProtocol_1 = require(\"../signalingprotocol/SignalingProtocol\");\nconst Transcript_1 = __importDefault(require(\"./Transcript\"));\nconst TranscriptionStatus_1 = __importDefault(require(\"./TranscriptionStatus\"));\nconst TranscriptionStatusType_1 = __importDefault(require(\"./TranscriptionStatusType\"));\nconst TranscriptItemType_1 = __importDefault(require(\"./TranscriptItemType\"));\nconst TranscriptionStatusTypes = {\n    [SignalingProtocol_1.SdkTranscriptionStatus.Type.STARTED]: TranscriptionStatusType_1.default.STARTED,\n    [SignalingProtocol_1.SdkTranscriptionStatus.Type.INTERRUPTED]: TranscriptionStatusType_1.default.INTERRUPTED,\n    [SignalingProtocol_1.SdkTranscriptionStatus.Type.RESUMED]: TranscriptionStatusType_1.default.RESUMED,\n    [SignalingProtocol_1.SdkTranscriptionStatus.Type.STOPPED]: TranscriptionStatusType_1.default.STOPPED,\n    [SignalingProtocol_1.SdkTranscriptionStatus.Type.FAILED]: TranscriptionStatusType_1.default.FAILED,\n};\nclass TranscriptEventConverter {\n    /**\n     * Decodes a list of TranscriptEvent from a data message.\n     * @param dataMessage Data message to decode from\n     * @returns List of TranscriptEvent\n     * @throws {Error} If the data message payload cannot be decoded\n     */\n    static from(dataMessage) {\n        let frame;\n        try {\n            frame = SignalingProtocol_1.SdkTranscriptFrame.decode(dataMessage.data);\n        }\n        catch (e) {\n            throw new Error('Cannot decode transcript data message: ' + e);\n        }\n        const transcriptEvents = [];\n        for (const sdkTranscriptEvent of frame.events) {\n            if (sdkTranscriptEvent.status) {\n                const transcriptionStatusType = TranscriptionStatusTypes[sdkTranscriptEvent.status.type];\n                if (!transcriptionStatusType) {\n                    continue;\n                }\n                const transcriptionStatus = new TranscriptionStatus_1.default();\n                transcriptionStatus.type = transcriptionStatusType;\n                transcriptionStatus.eventTimeMs = sdkTranscriptEvent.status.eventTime;\n                transcriptionStatus.transcriptionRegion = sdkTranscriptEvent.status.transcriptionRegion;\n                transcriptionStatus.transcriptionConfiguration =\n                    sdkTranscriptEvent.status.transcriptionConfiguration;\n                if (sdkTranscriptEvent.status.message) {\n                    transcriptionStatus.message = sdkTranscriptEvent.status.message;\n                }\n                transcriptEvents.push(transcriptionStatus);\n            }\n            else if (sdkTranscriptEvent.transcript) {\n                const transcript = new Transcript_1.default();\n                transcript.results = [];\n                for (const result of sdkTranscriptEvent.transcript.results) {\n                    const transcriptResult = {\n                        channelId: result.channelId,\n                        isPartial: result.isPartial,\n                        resultId: result.resultId,\n                        startTimeMs: result.startTime,\n                        endTimeMs: result.endTime,\n                        alternatives: [],\n                    };\n                    if (result.languageCode) {\n                        transcriptResult.languageCode = result.languageCode;\n                    }\n                    if (result.languageIdentification && result.languageIdentification.length > 0) {\n                        transcriptResult.languageIdentification = [];\n                        for (const languageIdentification of result.languageIdentification) {\n                            const transcriptLanguageWithScore = {\n                                languageCode: languageIdentification.languageCode,\n                                score: languageIdentification.score,\n                            };\n                            transcriptResult.languageIdentification.push(transcriptLanguageWithScore);\n                        }\n                    }\n                    for (const alternative of result.alternatives) {\n                        const transcriptAlternative = {\n                            items: [],\n                            transcript: alternative.transcript,\n                        };\n                        for (const item of alternative.items) {\n                            const transcriptItem = {\n                                content: item.content,\n                                attendee: {\n                                    attendeeId: item.speakerAttendeeId,\n                                    externalUserId: item.speakerExternalUserId,\n                                },\n                                startTimeMs: item.startTime,\n                                endTimeMs: item.endTime,\n                                type: null,\n                            };\n                            if (item.vocabularyFilterMatch) {\n                                transcriptItem.vocabularyFilterMatch = item.vocabularyFilterMatch;\n                            }\n                            if (item.hasOwnProperty('stable')) {\n                                transcriptItem.stable = item.stable;\n                            }\n                            if (item.hasOwnProperty('confidence')) {\n                                transcriptItem.confidence = item.confidence;\n                            }\n                            switch (item.type) {\n                                case SignalingProtocol_1.SdkTranscriptItem.Type.PRONUNCIATION:\n                                    transcriptItem.type = TranscriptItemType_1.default.PRONUNCIATION;\n                                    break;\n                                case SignalingProtocol_1.SdkTranscriptItem.Type.PUNCTUATION:\n                                    transcriptItem.type = TranscriptItemType_1.default.PUNCTUATION;\n                                    break;\n                            }\n                            transcriptAlternative.items.push(transcriptItem);\n                        }\n                        for (const entity of alternative.entities) {\n                            if (!transcriptAlternative.entities) {\n                                transcriptAlternative.entities = [];\n                            }\n                            const transcriptEntity = {\n                                category: entity.category,\n                                confidence: entity.confidence,\n                                content: entity.content,\n                                startTimeMs: entity.startTime,\n                                endTimeMs: entity.endTime,\n                            };\n                            if (entity.type) {\n                                transcriptEntity.type = entity.type;\n                            }\n                            transcriptAlternative.entities.push(transcriptEntity);\n                        }\n                        transcriptResult.alternatives.push(transcriptAlternative);\n                    }\n                    transcript.results.push(transcriptResult);\n                }\n                transcriptEvents.push(transcript);\n            }\n        }\n        return transcriptEvents;\n    }\n}\nexports.TranscriptEventConverter = TranscriptEventConverter;\n//# sourceMappingURL=TranscriptEvent.js.map","\"use strict\";\n// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n// SPDX-License-Identifier: Apache-2.0\nObject.defineProperty(exports, \"__esModule\", { value: true });\nclass TranscriptItem {\n}\nexports.default = TranscriptItem;\n//# sourceMappingURL=TranscriptItem.js.map","\"use strict\";\n// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n// SPDX-License-Identifier: Apache-2.0\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar TranscriptItemType;\n(function (TranscriptItemType) {\n    TranscriptItemType[\"PRONUNCIATION\"] = \"pronunciation\";\n    TranscriptItemType[\"PUNCTUATION\"] = \"punctuation\";\n})(TranscriptItemType || (TranscriptItemType = {}));\nexports.default = TranscriptItemType;\n//# sourceMappingURL=TranscriptItemType.js.map","\"use strict\";\n// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n// SPDX-License-Identifier: Apache-2.0\nObject.defineProperty(exports, \"__esModule\", { value: true });\n/*\n* When using automatic language identification for streaming transcription,\n* Amazon Transcribe provides the language codes of the identified languages and their associated confidence scores.\n* languageCode refers to one of language code from the set of languageOptions provided during start transcription call\n* score refers to the confidence score is a value between zero and one; a larger value indicates a higher confidence in the identified language.\n* Sample LanguageWithScore would look similar to this :\n* \"LanguageIdentification\": [\n                {\n                    \"LanguageCode\": \"en-US\",\n                    \"Score\": 0.805\n                },\n                {\n                    \"LanguageCode\": \"ja-JP\",\n                    \"Score\": 0.195\n                }\n            ]\n*/\nclass TranscriptLanguageWithScore {\n}\nexports.default = TranscriptLanguageWithScore;\n//# sourceMappingURL=TranscriptLanguageWithScore.js.map","\"use strict\";\n// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n// SPDX-License-Identifier: Apache-2.0\nObject.defineProperty(exports, \"__esModule\", { value: true });\nclass TranscriptResult {\n}\nexports.default = TranscriptResult;\n//# sourceMappingURL=TranscriptResult.js.map","\"use strict\";\n// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n// SPDX-License-Identifier: Apache-2.0\nObject.defineProperty(exports, \"__esModule\", { value: true });\nclass TranscriptionStatus {\n}\nexports.default = TranscriptionStatus;\n//# sourceMappingURL=TranscriptionStatus.js.map","\"use strict\";\n// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n// SPDX-License-Identifier: Apache-2.0\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar TranscriptionStatusType;\n(function (TranscriptionStatusType) {\n    TranscriptionStatusType[\"STARTED\"] = \"started\";\n    TranscriptionStatusType[\"INTERRUPTED\"] = \"interrupted\";\n    TranscriptionStatusType[\"RESUMED\"] = \"resumed\";\n    TranscriptionStatusType[\"STOPPED\"] = \"stopped\";\n    TranscriptionStatusType[\"FAILED\"] = \"failed\";\n})(TranscriptionStatusType || (TranscriptionStatusType = {}));\nexports.default = TranscriptionStatusType;\n//# sourceMappingURL=TranscriptionStatusType.js.map","\"use strict\";\n// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n// SPDX-License-Identifier: Apache-2.0\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n    return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\n// Use \"ua-parser-js\" over \"detect-browser\" to get more detailed information.\nconst ua_parser_js_1 = require(\"ua-parser-js\");\nconst Versioning_1 = __importDefault(require(\"../versioning/Versioning\"));\n/**\n * [[DefaultUserAgentParser]] uses UAParser to parse the browser's user agent.\n * It is responsible to hold and provide browser, OS and device specific information.\n */\nclass DefaultUserAgentParser {\n    constructor(logger) {\n        var _a, _b, _c, _d, _e, _f, _g;\n        try {\n            this.parserResult =\n                navigator && navigator.userAgent\n                    ? new ua_parser_js_1.UAParser(navigator.userAgent).getResult()\n                    : undefined;\n        }\n        catch (error) {\n            /* istanbul ignore next */\n            logger.error(error.message);\n        }\n        this.browserMajorVersion =\n            ((_c = (_b = (_a = this.parserResult) === null || _a === void 0 ? void 0 : _a.browser) === null || _b === void 0 ? void 0 : _b.version) === null || _c === void 0 ? void 0 : _c.split('.')[0]) || DefaultUserAgentParser.UNAVAILABLE;\n        this.browserName = ((_d = this.parserResult) === null || _d === void 0 ? void 0 : _d.browser.name) || DefaultUserAgentParser.UNAVAILABLE;\n        this.browserVersion = ((_e = this.parserResult) === null || _e === void 0 ? void 0 : _e.browser.version) || DefaultUserAgentParser.UNAVAILABLE;\n        this.deviceName =\n            [((_f = this.parserResult) === null || _f === void 0 ? void 0 : _f.device.vendor) || '', ((_g = this.parserResult) === null || _g === void 0 ? void 0 : _g.device.model) || '']\n                .join(' ')\n                .trim() || DefaultUserAgentParser.UNAVAILABLE;\n    }\n    getParserResult() {\n        var _a, _b;\n        return {\n            browserMajorVersion: this.browserMajorVersion,\n            browserName: this.browserName,\n            browserVersion: this.browserVersion,\n            deviceName: this.deviceName,\n            osName: ((_a = this.parserResult) === null || _a === void 0 ? void 0 : _a.os.name) || DefaultUserAgentParser.UNAVAILABLE,\n            osVersion: ((_b = this.parserResult) === null || _b === void 0 ? void 0 : _b.os.version) || DefaultUserAgentParser.UNAVAILABLE,\n            sdkVersion: Versioning_1.default.sdkVersion,\n            sdkName: Versioning_1.default.sdkName,\n        };\n    }\n}\nexports.default = DefaultUserAgentParser;\nDefaultUserAgentParser.UNAVAILABLE = 'Unavailable';\n//# sourceMappingURL=DefaultUserAgentParser.js.map","\"use strict\";\n// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n// SPDX-License-Identifier: Apache-2.0\nObject.defineProperty(exports, \"__esModule\", { value: true });\n/**\n * A simple promise queue to enforce the order of async APIs for example, start/stop video/audio input.\n */\nclass PromiseQueue {\n    constructor() {\n        this.queue = Promise.resolve();\n    }\n    // eslint-disable-next-line\n    add(func) {\n        return new Promise((resolve, reject) => {\n            this.queue = this.queue.then(func).then(resolve).catch(reject);\n        });\n    }\n}\nexports.default = PromiseQueue;\n//# sourceMappingURL=PromiseQueue.js.map","\"use strict\";\n// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n// SPDX-License-Identifier: Apache-2.0\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.None = exports.Some = exports.Maybe = void 0;\nclass Maybe {\n    static of(value) {\n        return value === undefined || value === null ? None.of() : Some.of(value);\n    }\n}\nexports.Maybe = Maybe;\nclass Some {\n    constructor(value) {\n        this.value = value;\n        this.isSome = true;\n        this.isNone = false;\n    }\n    map(f) {\n        return Maybe.of(f(this.value));\n    }\n    flatMap(f) {\n        return f(this.value);\n    }\n    get() {\n        return this.value;\n    }\n    getOrElse(_value) {\n        return this.value;\n    }\n    defaulting(value) {\n        return Maybe.of(this.getOrElse(value));\n    }\n    static of(value) {\n        if (value === null || value === undefined) {\n            throw new Error('value is ${value}');\n        }\n        return new Some(value);\n    }\n}\nexports.Some = Some;\nclass None {\n    constructor() {\n        this.isSome = false;\n        this.isNone = true;\n    }\n    get() {\n        throw new Error('value is null');\n    }\n    getOrElse(value) {\n        return value;\n    }\n    map(_f) {\n        return new None();\n    }\n    flatMap(_f) {\n        return new None();\n    }\n    defaulting(value) {\n        return Maybe.of(this.getOrElse(value));\n    }\n    static of() {\n        return new None();\n    }\n}\nexports.None = None;\n//# sourceMappingURL=Types.js.map","\"use strict\";\n// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n// SPDX-License-Identifier: Apache-2.0\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n    return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.iterateEvery = exports.SuppressedError = exports.getRandomValues = exports.getFormattedOffset = exports.getDefaultAssetSpec = exports.toLowerCasePropertyNames = exports.isIFramed = exports.wait = void 0;\nconst Versioning_1 = __importDefault(require(\"../versioning/Versioning\"));\nfunction wait(waitTimeMs) {\n    return new Promise(resolve => setTimeout(resolve, waitTimeMs));\n}\nexports.wait = wait;\n// This is impossible to adequately test in Node, so Istanbul ignore.\n/* istanbul ignore next */\nfunction isIFramed() {\n    var _a;\n    // Same-origin iframes can check `nodeName`.\n    // We can also check whether the parent window and the top window are the same.\n    // Cross-origin iframes will throw on the `parent` check, so catch here.\n    try {\n        return ((_a = window.frameElement) === null || _a === void 0 ? void 0 : _a.nodeName) === 'IFRAME' || parent !== top;\n    }\n    catch (e) {\n        // Very likely to be a cross-origin iframe.\n        return true;\n    }\n}\nexports.isIFramed = isIFramed;\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction toLowerCasePropertyNames(input) {\n    if (input === null) {\n        return null;\n    }\n    else if (typeof input !== 'object') {\n        return input;\n    }\n    else if (Array.isArray(input)) {\n        return input.map(toLowerCasePropertyNames);\n    }\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    return Object.keys(input).reduce((result, key) => {\n        const value = input[key];\n        const newValue = typeof value === 'object' ? toLowerCasePropertyNames(value) : value;\n        result[key.toLowerCase()] = newValue;\n        return result;\n    }, {});\n}\nexports.toLowerCasePropertyNames = toLowerCasePropertyNames;\n/**\n * Based on the SDK version, return an asset group.\n *\n * @returns the default asset spec, based on the SDK version.\n */\nfunction getDefaultAssetSpec() {\n    const version = Versioning_1.default.sdkVersionSemVer;\n    return {\n        assetGroup: `sdk-${version.major}.${version.minor}`,\n    };\n}\nexports.getDefaultAssetSpec = getDefaultAssetSpec;\n/**\n * Get UTC offset in (+|-)HH:mm format\n * E.g. For Asia/Calcutta timezone, +05:30 UTC offset value is returned\n */\nfunction getFormattedOffset(utcOffset) {\n    const offset = Math.abs(utcOffset);\n    const offsetOperator = utcOffset <= 0 ? '+' : '-';\n    const offsetHours = Math.floor(offset / 60)\n        .toString()\n        .padStart(2, '0');\n    const offsetMinutes = Math.floor(offset % 60)\n        .toString()\n        .padStart(2, '0');\n    return `${offsetOperator}${offsetHours}:${offsetMinutes}`;\n}\nexports.getFormattedOffset = getFormattedOffset;\nfunction getRandomValues(buffer) {\n    try {\n        // Browser environment\n        window.crypto.getRandomValues(buffer);\n    }\n    catch (error) {\n        // Node environment for unit test\n        const view = new DataView(buffer.buffer);\n        view.setUint32(0, Math.trunc(Math.random() * Math.pow(2, 32)), true);\n    }\n}\nexports.getRandomValues = getRandomValues;\n/**\n * Shim for SuppressedError\n * https://github.com/tc39/proposal-explicit-resource-management?tab=readme-ov-file#the-suppressederror-error\n */\nclass SuppressedError extends Error {\n    constructor(\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    error, suppressed, message) {\n        var _a;\n        /* istanbul ignore next -- because coverage can't detect all the branches */\n        super(message !== null && message !== void 0 ? message : `${(_a = error === null || error === void 0 ? void 0 : error.message) !== null && _a !== void 0 ? _a : error}`);\n        this.error = error;\n        this.suppressed = suppressed;\n    }\n}\nexports.SuppressedError = SuppressedError;\n/**\n * Run a callback over the set of all values, suppress any errors, and only throw after iteration completes.\n * @param iterable - The iterable to iterate over\n * @param callback - The callback to run on each iteration\n * @throws If any of the callbacks throw an error\n */\nfunction iterateEvery(iterable, callback) {\n    if (!iterable)\n        return;\n    let suppressedError;\n    for (const value of iterable) {\n        try {\n            callback(value);\n        }\n        catch (err) {\n            suppressedError = new SuppressedError(err, suppressedError);\n        }\n    }\n    if (suppressedError) {\n        throw suppressedError;\n    }\n}\nexports.iterateEvery = iterateEvery;\n//# sourceMappingURL=Utils.js.map"],"names":[],"sourceRoot":""}